他のパラダイムの前に関数型プログラミングを学ぶことについて、長所と短所は何ですか?
主な問題の1つは、Haskellのような言語で始めた場合、他のすべてが標準以下に見えるようになることです。
正直なところ、Haskellやschemeなどの言語から始めるのは素晴らしいアイデアだと思います。
(私は関数型言語の常習者であることを認めます)編集:
私が両方の言語について好きなものをOK:
Schemeは、非常に単純な言語を取り、それから、開発のための非常に堅牢な言語を構築します。また、SICPは、そこで学ぶ価値のあるスキームについて書かれています。スキームとは、あなたが想像できる最も単純なものであり、それが完全な言語であり得るということです。
Haskell本当に成長しているのは型システムです。他の言語で見られるバグの多くは、どこかに間違ったタイプが表示されていることが原因です。 Haskellではそれはほとんど不可能です。また、怠惰な言語のアイデアは、それからいくつかのクールなものが落ちているだけです。たとえば、Haskellで無限のデータ構造を作成してから、必要な部分だけを作成できます。
OOP langを学習する前に関数型言語を学習する最大の利点は、プログラミングスキルが最初に開発され、次にOOPの概念を簡単に理解できることです。 OOP言語で開始するのは簡単です。 "コードについて考える"と "OODについて考える"という2つのことを同時に学ぶ必要があります。関数型言語を使用してプログラミングスキルを開発します。次にOOPおよびその他のパラダイムを学習します。OOPは構造プログラミングの不足を補うために設計されたので、簡単になりますそれがCSコースがCで始まり、C++に進む理由です。
どのように関数プログラミングから始めてプログラミングを学ぶかの問題について、2つの古典的な推奨事項:
最初の明白なものは、AbelsonとSussmanによる古典的なコンピュータプログラムの構造と解釈であり、これは、CSの最良の紹介の1つであり、 Schemeを使用した機能的観点。 フルオンラインで利用可能 です。ここから始めない場合は、いくつかのポイントとしてここにアクセスする必要があります。
同じ分野のほとんどを穏やかなペースでカバーし、ソフトウェアエンジニアリングに重点を置いた最新のテキストは、How to Design Programs、Matthew Felleisenおよび他の多くのSchemeのラケット方言を使用するラケット/ PLTチーム。進行中の 第2版 と同様に、 オンラインでも利用可能 です。この本には、DrRacketプログラミング環境で使用するように設計されているという利点があり、初心者にもエキスパートにも、コードを試すための非常にフレンドリーなインターフェースを提供します。
なぜ関数型プログラミングから始めるのかという質問で、私は Bob Harperのブログ を指摘したいと思います。カーネギーメロンは最近、関数型プログラミングを最初に教えるためにCSカリキュラムを再編成しました。ハーパーは彼のブログで彼らの進歩をブローバイブローでカバーしています。標準MLの定義の背後にいる人物の1人として、彼がこの動きに賛成していることは明らかであり、彼はその理由をよく主張しています。
最後に、私は最初にHaskellを学ぶことに対して警告しますが、他の人は同意しないかもしれません。 HaskellのFPへの純粋なアプローチは確かに良い習慣を生み出しますが、遅延計算に焦点を当てた言語は、必ずしも初心者に適しているとは限りません。最初に必要となる最も重要なことの1つです。プログラマーとして行うことを学ぶことは、ソースを見てプログラムが何をしているかを正確に推論することと、同じ問題への異なるアプローチの相対的なコストについてです。あなたのマイレージは変化するかもしれませんが、経験豊富なプログラマーにとってさえ挑戦の。
FPで開始することの主な利点(または非欠点)は、ほとんどの概念が命令型プログラミングにも適用できることです。 ラケットの領域 は、ビデオゲームの類義語を使用して、機能的概念と命令的概念の両方を教えます。熱心な学生は、機能的ゲーム(npi)だけでなく、条件、再帰、ループ、ADT、イベント駆動型の設計。これらの概念は、現代のプログラミングでは事実上ユビキタスであり、常に使用されています。
ただし、さらに重要なことは、高次の関数とデータ型を使用してFPが優れている抽象化をエンコードする方法を学習することです。 プログラムの設計方法 は、誘導を通じて教えることにより、これに対して独自のアプローチをとります。たとえば、リストの合計と積の両方を取得するコードを調べ、共通点を見つけ、実装自体を導出することにより、fold
がどのように機能するかを学習します。
上記のOOPには、インターフェイス、抽象クラス、ジェネリックス、ファンクター、または(間違っている場合は)シングルトンの1つ以上が含まれる可能性があります。これらはJavaで完全に受け入れ可能な設計パターンですが、IMHOは入門カリキュラムに属しておらず、基礎となる原則を難読化するためにのみ役立ちます。 FP言語に「遅れて」導入された人でも、強力な機能アンカーを使用することで、変化し続けるOOPの海をナビゲートすることが非常に簡単になったと言えます。
関数型プログラミングは、物事をはるかに簡単にします。 OOP言語では、状態を台無しにせずに複数のスレッド間で状態を管理する必要があります。関数型言語では、行われている作業の大部分が純粋な関数によって行われている場合、それについて心配する必要があります。
スピード/パフォーマンスの点では、私は本当のパフォーマンスジョッキーではありませんが、関数型であることは遅いという意味ではなく、関数型言語の構造はそれらの速度とほとんど関係がありません。関数型言語の構文は、ClojureとHaskellの違いなど、大きく異なります。 Clojureはそのままの状態で非常に高速であり、事後最適化によりJava)の速度に達する(場合によっては超える)ことができます。
つまり、すべては本当にあなたが探しているものに依存します
プログラミング言語を学ぶ際には、学習資料、いくつかの優れたコードサンプル、メンターが利用できることが非常に重要だと思います。状況によっては、教えてくれるメンターなどがいるかもしれませんが、主流の言語に比べて関数型言語のリソースは非常に少ないと思います。それはあなたが主流の言語を学ぶことと比較してゆっくりと進歩することを意味します。しかし、あなたが急いでいなければ、これは問題ではありません。
おそらく、関数型プログラミング言語の学習を検討する最も重要な理由は、代数的データ型の理解です。メンタルマッピングは、OOクラスの関係やデータベース設計さえもモデリングするのに役立ちます。
マルチコア/マルチプロセッサシステムへの焦点は、FPでより明確かつ簡潔に表現できる並列アルゴリズムの使用に重点を置いています。言語のラムダブランチでは、今後10〜20年で使用が大幅に増加する可能性があります。
しかし、いくつかの一般的な落とし穴もあります。 FPの方が単純であると信じるのは大きな間違いです。空間と時間の複雑さを計算すること、および停止の証明を提供することは、特に遅延評価をサポートする言語ではラムダ計算ではるかに困難になる可能性があるためです。
だから、両方を学びましょう!あるいは多分もっと良い:最初にScalaのような両方を包含する言語を学びなさい。タイダイTシャツと少しオランダのアクセントが気にならない場合は、MSDNに掲載されている Erik Meijer博士によるFP講義 が役立つでしょう。