web-dev-qa-db-ja.com

最も純粋な関数型プログラミング言語ですか?

関数型プログラミングの学習に興味があります。そのためには、可能な限り純粋な関数型プログラミング言語を使用するように強制する必要があることは明らかです。したがって、関数型プログラミング言語の純度に応じた順序付けを、多かれ少なかれここに求めています。

LISPやClojure(またはScheme、Scalaなど)を学ぶ方が実際的であるように思えますが、最近聞いたところによると、関数型プログラミングの原則を誰かに教えるのはHaskellの方が難しいでしょう。これについてはまだわかりませんので、私はあなたに質問しています:最も純粋な関数型プログラミング言語ですか?複数の人が最も純粋な関数型プログラミング言語の壮大なタイトルをめぐって争っているなら、順序は素晴らしいでしょう。

20
Joanis

関数型言語の純度の程度を評価する尺度はありません。言語が副作用を許可する場合、それは不純であり、それ以外の場合、それは純粋です。この定義では、Haskell、Mercury、Cleanなどは純粋な関数型言語です。一方、Scala、Clojure、F#、OCamlなどは不純なものです。

編集:多分私はこれを「言語が型システムに知らせずに副作用を許可しない場合と表現するべきだったはずです。それ以外は純粋ではありません。 ……」.

28
missingfaktor

学習が目標であり、プログラムを書くことではないのでそれ自体、ラムダ計算 よりも純粋なものは得られません。

ラムダ計算は、コンピューターが発明される前からありました。減算の方法を理解するには、熟練した論理学者が何人か必要でした(しばらくの間、加算と乗算のみが可能であると理論化されていました)。

ブール値と数値、およびifをどのように発明できるかを学習しても、タンクにガスを追加することはできませんが、タンクが大きくなります。

15
Macneil

不純な言語は、特に多くの機能的なトリックがコピーされた今、特に、より馴染みのある命令型言語と実際には違いません。違いはスタイルです。問題をどのように解決するかです。

Haskellを純粋と見なしても、IOモナドを不純と見なしても、Haskellスタイルはこのスタイルの極端な形式であり、学ぶ価値があります。

Haskell IOモナドは(もちろん)モナドの数学的理論から派生していますが、命令型プログラマーにとっては、モナドに逆方向に到達する方法の方が理にかなっていると思います。

フェーズ1-純粋な関数型言語は、結果として大きな文字列値を簡単に返すことができます。この大きな文字列は、いくつかの要件指定パラメーターから純粋な機能的な方法で派生した命令型プログラムのソースコードになる可能性があります。次に、コードジェネレーターを実行する「高レベル」コンパイラーを構築し、生成されたコードを命令型言語コンパイラーに自動的にフィードします。

フェーズ2-テキストのソースコードを生成するのではなく、強く型付けされた抽象構文ツリーを生成します。命令型言語コンパイラーは「より高いレベル」のコンパイラーに吸収され、ASTをソースコードとして直接受け入れます。これはHaskellの動作に非常に近いものです。

しかし、これはまだ厄介です。たとえば、コード生成フェーズで評価される関数と、生成されたプログラムの実行時に実行される関数の2種類の関数があります。これは、C++の関数とテンプレートの違いに少し似ています。

したがって、フェーズ3では、2つを同じにします。同じ構文の同じ関数は、「コード生成」中に部分的に評価されるか、完全に評価されるか、まったく評価されない可能性があります。さらに、すべてのループ構造ASTノードを再帰的に優先して破棄します。実際には、ASTノードの特別な種類のデータとしてのノードをすべて破棄します-しないでください。 t "リテラル値"があるASTノード、値があるだけなど。

これは、IOモナドが行うこととほぼ同じです。バインド演算子は、プログラムを形成するための「アクション」を作成する方法です。特別なことではありません。単なる関数です。多くの式と関数は、 「コード生成」ですが、I/Oの副作用に依存するものは、特別な規則ではなく、式のデータ依存性の自然な結果として、実行時まで評価を遅延させる必要があります。

一般にモナドは単なる一般化です。それらは同じインターフェースを持っていますが、抽象演算を異なる方法で実装しているため、命令コードの説明に評価する代わりに、何か他のものに評価します。同じインターフェースを持つことは、どのモナドを気にせずにモナドにできることがいくつかあることを意味します。

この説明は間違いなく純粋主義者の頭を爆発させるでしょうが、私にとっては、Haskellが興味深い理由のいくつかを説明しています。プログラミングとメタプログラミングの境界をぼかし、関数型プログラミングのツールを使用して、特別な構文を必要とせずに命令型プログラミングを再発明します。

私がC++テンプレートについて批判しているのは、それらが命令型言語の一種の壊れた純粋な関数型サブ言語であることです-実行時ではなくコンパイル時に同じ基本関数を評価するには、完全に異なるスタイルを使用して再実装する必要がありますコーディングの。 Haskellでは、不純物はその型でそのようにラベル付けする必要がありますが、まったく同じ関数をメタプログラミングの意味と同じプログラムのランタイム非メタプログラミングの意味の両方で評価できます-難しい行はありませんプログラミングとメタプログラミングの間。

そうは言っても、基本的に型(および他のいくつかのこと)がファーストクラスの値ではないため、標準のHaskellでは実行できないいくつかのメタプログラミングがあります。ただし、これに対処しようとする言語バリアントがあります。

Haskellについて私が述べたことの多くは、純粋でない関数型言語、そして時には命令型言語にも適用できます。 Haskellは、このアプローチを取る以外に選択肢がないため、違います。基本的に、このスタイルの作業を学ぶことを強制します。 「CをMLで書く」ことはできますが、「CをHaskellで書く」ことはできません。

6
Steve314

私は言語を機能的に純粋な3つの層に分類しています。

  • 純粋な関数型言語-つまり、プログラム全体を純粋な関数として扱い、ランタイムとの対話のみを通じて可変性を処理する言語-Haskellおそらく標準的な例です

  • 不純な関数型言語-つまり、関数型のスタイルを強調しながら副作用を許容する言語。 Clojureは明らかにこのカテゴリに含まれます(STMフレームワークの一部として制御された方法で変異を許可します)、また OCamlまたはF#

  • マルチパラダイム言語-これらは何よりも関数型言語ではありませんが、ファーストクラスの関数などを使用して関数型スタイルをサポートできます。Scalaはここでの良い例です。Common LISPもこのカテゴリに追加し、JavaScript

あなたの状況では、まずHaskellを学び、次にClojureを学ぶことをお勧めします。これは私がやったことであり、それは私にとって非常にうまくいきました! Haskellは美しく、最も純粋な機能原理を教えてくれます。Clojureはより実用的であり、中心的な機能を維持しながら多くのことを成し遂げるのに役立ちます。

私は実際には3番目のカテゴリを関数型言語として数えていません(ただし、HaskellとClojureを学んだ後、それらを使用するときに関数型のテクニックを利用することがよくあります!)

5
mikera

純粋な関数型言語が純粋な関数(副作用のないルーチン)しかない場合、入力の読み取りや出力の書き込みができないため、少し無意味です。;)

これは実際に学習するためのものなので、分離は必ずしもに進むべきものではないと思います。関数型プログラミングはパラダイムです。どのパラダイムがどの問題に適しているかを理解することが重要です。さらに重要なのは、どのパラダイムを最適に組み合わせることができるかです。

私は今それを言うつもりです:プログラミングのファッションは愚かで逆効果です。重要なことは、プログラムが短く、書きやすく、保守が容易で、正しく機能することだけです。これを達成する方法は、プログラミングの流行とは何の関係もありません。 - リチャードジョーンズ

それ以外に、「純度」を探している場合は、 Pure を確認することをお勧めします。ただし、Cルーチンの呼び出しは非常に簡単であるため、機能的には純粋ではありません(ただし非常に強力です)。

3
back2dos

完全に深刻な答えではありませんが、 nlambda は候補者である必要があります。 S K Iコンビネータよりも「純粋な機能」を得ることができません。

3
Stephen C

Erlang、Haskell、Scheme、Scala、Clojure、F#

この質問は、おそらく well として検索に役立つでしょう。

2
dustyprogrammer