私は今週末、LISPを真剣に検討し始め(つまり、LISPを学習しているだけで、C#のプロジェクトに戻っていないことを意味します)、大好きだと言わなければなりません。他の関数型言語(F#、Haskell、Erlang)を試してみましたが、LISPから得られた魅力を感じていません。
LISPの学習を続けている今、非関数型言語がファーストクラスの関数をサポートしていない理由を知り始めました。 C#などの言語はデリゲートを使用して同様のことを実行でき、C/C++の関数へのポインターを使用できる範囲で知っていますが、これがこれらの言語の機能にならない理由はありますか?関数をファーストクラスにすることに欠点はありますか?私にとって、これは非常に便利です。そのため、(関数型パラダイム以外の)より多くの言語がそれを実装しない理由が分からなくなります。
[編集]これまでの回答に感謝します。現在、多くの言語がファーストクラスの関数をサポートしていることが示されているので、言語がそれらを実装するのになぜこんなに時間がかかるのかという質問に言い換えます。 [/編集]
ファーストクラスの関数は、クロージャーなしではそれほど面白くありません。
何らかの動的なスコープ管理(ガベージコレクション)がなければ、クロージャは実際には不可能です。 C/C++を非常に高性能にする理由の1つは、メモリを手動で管理する言語をコンパイルする方がはるかに簡単であるため、C/C++を計算式から除外することです。
そして、はい、OOP影響の問題があります。メソッドとプロパティの分離はなくなりました。メソッド自体は、関数を値として受け入れるプロパティです。その文脈では、メソッドをオーバーロードするとはどういう意味ですか?たとえば、言語全体に大きなパラダイムシフトを導入せずに、それをJavaに本当に追加できますか?コントラクトはどこにあるのでしょうか。または、構成要素が常に同じように機能することが保証されていることを知っていることから人々が得るセキュリティ(IMO false)の意味は何ですか?オブジェクトに関連付けられた関数をメソッドとして別の生物として扱うことは、最初は独立して関数を存在させることができたが、実際にはオプションではないJavaに存在することを許可した場合に意味があります。
JavaScriptでは、OOPと機能が非常に絡み合っており、ファーストクラスのファンクが、そうでない言語にボルトオンされた以外の何物であるかを個人的に見るのは難しいと思います。しかし、そのためには、オブジェクトとそのメソッド自体の高レベルの可変性や、あたかもオブジェクトがその場でオブジェクトのメンバーであるかのように関数を呼び出すことができるなど、パラダイムシフトを変更する必要があります。
言語は、ほとんどのことを実行するためのdo-hickeyでいっぱいのツールセットだけではありません。彼らはパラダイムです。あらゆる種類のアイデア、戦略、および意見をまとめたものであり、関連している(または関連しているように見える)方法でまとめられています。多くの場合、名詞と動詞は実際にはパラダイムにまったく適合しないか、せいぜい不完全な適合として機能します。
とは言っても、腕なしでコーディングすることを余儀なくされたとき、私は腕が欠けているように感じます。
C#、VB.NET、Python、JavaScript、さらにはC++ 0xでさえ、ファーストクラスの関数を提供します。
更新:
クロージャーの実装にはラムダリフティングが必要です。これは、本来、命令型プログラマーにとって非常に異質な手法です。適切なファーストクラスの関数(クロージャーを含む)には、少なくともランタイムとVMからのサポートが必要です。また、古い機能的手法を命令型の世界に採用するのにも時間がかかりました。
そして、最も重要な部分-ガベージコレクションが存在しない場合、ファーストクラスの関数はほとんど使用できません。 Java、およびその結果、.NETを使用して、最近になって大量プログラミングに導入されました。そして、元のJavaのアプローチは、 .NETが最初に続き、つい最近になって(IMHO、かなり正当化され、適切な)方向から離れました。
このようなコンセプトはすべて、業界で消化されるまでに時間がかかります。
それは本当に不可能ではありません。しかし、これはさらに別の機能であり、複雑さの予算は限られています。それは言語デザイナーによって不必要であると考えられるかもしれません(あるいは、それが起こることすらありません)-「なぜ関数を渡す必要があるのですか?この言語はOSのプログラミング用です!」。また、言語の残りの部分とマージするのにかなりの労力がかかるかもしれません。たとえば、関数型では、型システムに深刻な追加が必要になる場合があります(Javaなど)。オーバーロードが発生している場合はさらに必要になります(@Renesisに指摘してくれたことに感謝します)。また、実行可能なコードを使用するためにいくつかのライブラリコードを提供する必要があります。誰もmap
を自分で定義する必要はありません。
また、言語の他の目標を達成するのが難しくなる可能性もあります。
f
が再割り当てされないことを証明する必要があります。同じように、なぜプログラミング言語L1にも非常に異なる言語L2の特徴Fがないのかと考えることができます。
最初の問題は、オブジェクト指向と機能を混在させることができないという誤解だと思います。 JavaScript 、 ActionScript 、 Python 、 C# の両方として、少なくともWikipediaで説明されている言語のクイックリスト、 F# 。
2番目の問題は first-class functions の定義のようです-たとえば、なぜC#にそれらがあると考えないのですか?
私は関数型言語の専門家ではないので、私が間違っている場合はコメントで訂正してください。しかし、私の理解では、ファーストクラスの関数自体を含めることで、言語が関数型パラダイムをサポートするかどうかを定義します。
したがって、オブジェクト指向言語canも機能的であり、これらの言語にはファーストクラスの関数が含まれていることを理解すると、探している質問は一部のオブジェクト指向言語にはファーストクラスの関数が含まれていませんか?
この主な理由の1つは、言語が function overloading (Javaの例)をサポートすることも選択している場合に、ファーストクラスの関数を定義するのが難しいことです。
public int dispatchEvent(Event event);
public int dispatchEvent(String event, Object data);
変数が参照するdispatchEvent
関数はどれですか?
クラスベースのプログラミングは、言語がファーストクラスのオブジェクトをサポートすることを妨げるものではありませんが、混乱を招いたり、回答する質問を追加したりできます。
たとえば、ECMAScript言語としてのActionScriptは、JavaScriptのようなはるかに機能的なパラダイムから始まりました。関数は本質的にオブジェクトにバインドされていませんでした。実行時にスコープとなるため、基本的に任意のオブジェクトで呼び出すことができました。
(動的ではない)クラスを追加すると、クラス自体だけでなく、インスタンスにバインドされたinherentlyの関数があります。これはFunction.apply
の仕様にいくつかのしわを投げます。私は正直に彼らがどのようにそれを扱ったかを知るために掘り下げていません。
私も同じことを考えていました。ラムダ語の言語になったら、LOTを使用します。でもPHPは、PHP 5.3でクロージャーを実行できることがわかったときに改善されます(LISPほどではありませんが、より優れています)。