19

すべての関数型言語は、関数をプログラムの基本的な構成要素として使用するなど、いくつかの基本的なプロパティを共有し、反復の代わりに再帰を使用するなどのすべての結果をもたらすことが知られています。ただし、いくつかの根本的な違いもあります。Lisp は Lisp コードとデータの両方に単一の表現を使用しますが、ML には ML コードの標準表現はありません。Erlang には組み込みのアクターベースの同時実行性があります。Haskell にはモナドがあります。Haskell は、静的型システムで純粋関数と非純粋関数を区別しています。ML にはありません。

他の関数型言語 (Clojure、F#、Arc、その他) との根本的な違いは何ですか? 基本とは、この言語で開発する方法に影響を与える何かを意味し、たとえば、それが広く普及したランタイムと統合されているかどうかではありません。

4

7 に答える 7

26

私の頭の上から:

  • lazy vs.eager (非厳密vs. strictまたはcall-by-need vs. call-by-value とも呼ばれます): 関数の引数は関数適用の前に評価されますか、それとも後で評価されますか?
  • 純粋vs.不純: 言語は、関数が副作用を持つことを許可していますか? 可変参照はありますか?
  • 静的動的: 言語はコンパイル時または実行時に型をチェックしますか?
  • 代数的データ型: 言語はバリアント型に対するパターン マッチングをサポートしていますか?
  • メタプログラミング: 言語は強力なコード生成システムを提供しますか?
  • 並行性並列性: スレッド/プロセスは第一級の抽象化ですか? この言語では、複数の計算を同時に簡単に実行できますか?
  • 「エキゾチックな」型: 静的型システムの表現力は? GADT? 依存型?線形タイプ?システムF?

最初の 2 つの項目だけが関数型言語に固有のものです (つまり、ほとんどすべての命令型言語は熱心で不純です)。

于 2009-01-28T01:54:45.800 に答える
14

さまざまな関数型言語を分類するのに役立ついくつかの重要な軸を述べている Chris Conway の回答が気に入っています。

特定の言語の機能に関しては、他の多くの FPL にはないいくつかの機能を呼び出すためにF#を選びます。

  • アクティブ パターン: 多くの FPL には代数データ型とパターン マッチングがありますが、「アクティブ パターン」と呼ばれる F# 機能を使用すると、任意のデータに対してパターン マッチング構文を使用できる新しいパターンを定義できます。
  • 計算式: F# には、モナド コードを作成するための美しいシンタックス シュガーがあります。型システムはより高次のポリモーフィズム (型構築子に対する抽象化なし) を表現できないため、任意のモナド M のコードを書くことはできませんが、固定モナドのコードを書くことは非常にクールであり、人々はいくつかの優れた内包表記をseq{} または async{} モナド。
  • Quotations : 通常の「メタプログラミング用のデータとしてのコード」ビット。

一般的な分類では、F# は

  • 熱心な(厳密な、値による呼び出し。ただし、'lazy' はキーワードとライブラリであり、いくつかの怠惰のために seq/IEnumerable を使用するのが一般的な戦略です)
  • 不純(ただし、構文により、デフォルトでより純粋なスタイルにバイアスがかかります)
  • static (型推論を使用するため、F# は多くの場合「スクリプトのように感じる」、型安全性のみ)

あなたの質問は、いくつかの言語外の語用論(たとえば、どのランタイムと統合するか)に対して明確な偏見を持って表現されていますが、「開発方法に影響を与える」ものも尋ねます。これらのことはそれに影響を与えます:

  • Visual Studio との統合は、優れた編集エクスペリエンスを意味します(例: Intellisense)
  • Visual Studio との統合は、優れたデバッグ エクスペリエンスを意味します (例: ブレークポイント/トレースポイント、ローカル、即時ウィンドウなど)。
  • スクリプティングまたは UI オンザフライのREPLは重要です (fsi.exe コマンドライン、または VS に統合された "F# Interactive")
  • .NET 統合は、ほとんどの 'X' に対して、それを行うためのライブラリが既に存在することを意味します
  • FsLex/FsYacc などのサイド ツール、および「システムのビルド」を容易にする MSBuild との統合

(言語をそのランタイムとツールから分離しようとすることは、ほとんど学術的な課題だと思います。)

だから、私がファンである特定の言語の多くの特徴的な機能の説明があります. 他の個々の言語の特徴を引き出す同様の回答を他の人が投稿してくれることを願っています。

于 2009-01-28T13:43:48.867 に答える
9
  1. 非厳密対厳密な評価。

  2. 静的型付けと動的型付け。

  3. 構造的対公称静的型付け。OCaml は、構造型付け (オブジェクトとポリモーフィック バリアントの両方) で私が考えることができる唯一の言語です。これは、多くの型 (バリアント型など) を定義する必要をなくすことで、動的型付けとのギャップを埋めます。

  4. Hindley-Milner 派生物と他の静的型推論アルゴリズムの比較。SML、OCaml、Haskell、および F# は Hindley-Milner に基づく型推論アルゴリズムを使用しますが、Scala は (C# 3 のように) ローカル型推論のみを行い、コンパイルにはさらに多くの注釈が必要です。(Haskell コードは多くの場合、関数レベルの型注釈でいっぱいですが、ほとんどは不要であり、ドキュメント用に追加され、エラーが発生した場合にコンパイラを支援します)。

  5. パターン マッチングと手動分解。SML、OCaml、F#、Haskell、Mathematica、Scheme は、値の分解を自動化します。

  6. クローズドサムタイプとオープンサムタイプのみ。SML、OCaml、F#、および Haskell では、より具体的な制約を暗黙的に伝達することで静的型付けを強化するために、閉じた/封印された代数型を定義できます。OCaml と F# も open sum 型を許可しますが、SML はそうではなく、Haskell は入念な回避策を必要とします (Oleg Kiselyov によって説明されています)。

  7. 制限時間パターン。パターン マッチングは SML と (バニラ) OCaml では非常に高速ですが、F# ではアクティブなパターンが原因でパフォーマンスが不明であり、Mathematica では漸近的な複雑ささえ不明です。

  8. ネイティブ コードへのオンザフライ コンパイル。F#、Lisp、Scheme を使用すると、コードを実行時に効率的に生成、コンパイル、実行できます。

  9. マクロ。OCaml、Mathematica、Lisp、Scheme は拡張可能な言語です。

  10. 標準化と独自仕様。SML、Haskell 2010、Common Lisp、Scheme は標準化された言語ですが、OCaml、Erlang、F#、Mathematica は独自仕様です。

于 2009-05-06T03:05:18.067 に答える
5

多くの違いがありますが、開発に大きな違いをもたらすという点で、基本的な違いとして分類できるのは次の 2 つだけです。

  1. 代数データ型と型推論を備えた、動的に型付けされた対静的な多相型システム。静的型システムはコードを多少制限しますが、多くの利点があります。
    • 型は、コンパイラによってチェックされるドキュメントです。
    • 型システムは、次に記述するコードを選択するのに役立ちます。また、何を記述すればよいかわからない場合、型システムを使用すると、多くの代替案を簡単かつ迅速に除外できます。
    • 強力で最新のポリモーフィック型システムは、小さくてばかげた、時間を浪費するバグの検出に不当に優れています。
  2. どこでもデフォルトとしての遅延評価と、慎重に制御された構造に制限された遅延評価。
    • 怠惰と熱心は、プログラムの時間とスペースのコストを予測して理解する能力に大きな影響を与えます。
    • 完全に怠惰な言語では、一度生成されたデータをどうするかについての決定から、データの生成を完全に切り離すことができます。これは、コードのモジュール化と再利用がはるかに容易になるため、検索の問題では特に重要です。
于 2009-01-30T03:10:23.753 に答える
3

関数型プログラミングはスタイルであり、言語構造ではありません

ほとんどの関数型言語には、いくつかの共通の原則があります。

  • 不変オブジェクト
  • クロージャーと無名関数
  • 汎用アルゴリズム
  • 継続

しかし、最も重要な原則は、通常、機能的なスタイルで書くことを強制するということです。ほとんどの言語で関数型のプログラミングを行うことができます。C# は、そのようなコードを記述した場合、他の言語と同様に「機能的」と見なすことができます。

于 2009-01-27T21:47:45.143 に答える
2

コードをデータと言うときは、コードがデータ構造で表される言語を指します。これは同像性と呼ばれ、通常、Lisp方言またはそれに近い言語である言語にのみ当てはまります。Haskell、Erlang、Scalaは同像性ではなく、Clojureは同像性です。

Clojureの基本的な差別化要因は次のとおりです。

  1. ソフトウェアトランザクショナルメモリシステムを備えているため、共有状態の並行プログラミングが容易になります。

  2. HaskellやErlangとは異なり、Lispであるため、すべてのコードはデータであり、マクロシステムを介して実行時に言語自体にどのように見えるかを変更できます。

  3. JVM上で実行されるため、すべてのJavaライブラリに直接アクセスできます。

  4. Clojureデータ構造は、必要に応じて、Collection、List、Map、Runnable、CallableなどのJavaインターフェースを実装します。文字列は単なるJava文字列であり、数値はJava整数と倍精度浮動小数点数です。これは、Clojureデータ構造をブリッジングや変換なしでJavaライブラリーに直接渡すことができることを意味します

于 2009-01-28T01:12:52.297 に答える
2

基本特性?

  • 機能的純度(副作用の欠如)
  • 以上からのつなぎとして、欠品状態。
  • 関数でのパターン マッチング

1 つ目は美しく、2 つ目は前者の醜い副作用です (しゃれが意図されています)。

状態の欠如に対する現実世界の補償は、関数型言語間の最大の差別化要因であると私が見つけたものです。

これらのいくつかのことは、多くの景品を提供します。ほとんどの場合、言語はメモ化を処理します。

于 2009-01-27T21:47:57.670 に答える