静的に型付けされた関数型プログラミング言語を使用しない10の理由

翻訳者から

これは、なぜ人々が関数型言語を恐れているか、皮肉とユーモアがある理由についての記事の無料翻訳です



著者について


私は英国の非ソフトウェア会社の開発者および建築家です。 高レベルのUX / HCIから低レベルのデータベース実装まで、さまざまな分野で20年の経験があります。

私は日々の仕事でC#を使用しているという事実にもかかわらず、私は多くの言語、私のお気に入りのSmalltalk、Python、そして最近ではF#で産業用コードを書きました(だからこのサイトを作成しました )。





わからないことを思いつく



関数型言語に関するこのような誇大広告にうんざりしていませんか? 私も! あなたや私のような理にかなった人々がこれを避けなければならない理由をいくつかあげます。



少し説明します。「静的に型付けされた関数型プログラミング言語」と言うとき、デフォルトの型推論などをサポートする言語を意味します。 実際には、これはHaskellおよびMLファミリーの言語(OCamlおよびF#を含む)を意味します。



理由1.最新のトレンドをフォローしたくない



ほとんどのプログラマーのように、私は保守的であり、新しいことを学ぶのが好きではありません。 それが私がITでのキャリアを選んだ理由です。

私はすべての「タフな男たち」がやるからという理由だけで大衆の趣味に屈しません。まず物事が成熟するまで待ち、いくつかの視点を見ることができます。

私にとって、関数型プログラミングはまだまだ短すぎて、ここに本気で永久に存在することを確信させることはできません。

はい、 MLHaskellはJavaとPHPの古いお気に入りとほぼ同じくらい存在すると反論する人もいると思いますが、ごく最近Haskellについて聞いたので、この議論はまったく納得できません。



このファミリーの新人、 F#を見てみましょう。 主よ、彼はわずか7歳です! もちろん、これは地質学者にとっては十分な時間かもしれませんが、インターネットの時代では、7年は瞬く間に過ぎません。

したがって、関数型プログラミングが残っているか、期待どおりに動作していないかを確認するために、私は間違いなく注意して数十年待つことになります。



理由2。コードの行に対して支払いを受ける



あなたのことは知りませんが、書いたコードの行が多ければ多いほど、私は生産性を感じます。 1日500行をスタンプできる場合、ジョブは正常に完了しています。 私のコミットは大きく、上司は私が忙しかったことを確認できます。

しかし、関数型言語で書かれたコードを古き良きC言語に似た言語と比較すると、コードが非常に少ないので怖いです。

私が言っていることを見てください、ここに通常の言語で書かれたコードがあります:

public static class SumOfSquaresHelper { public static int Square(int i) { return i * i; } public static int SumOfSquares(int n) { int sum = 0; for (int i = 1; i <= n; i++) { sum += Square(i); } return sum; } }
      
      







そして、これと比較してください:

 let square x = x * x let sumOfSquares n = [1..n] |> List.map square |> List.sum
      
      





2行のみに対して17行。 これにプロジェクトのサイズを掛けた場合の違いを想像してください

これを使用すると、生産性が急落します。 申し訳ありませんが、それを買う余裕はありません。



理由3.中かっこが大好き



そしてもう一つ。 中括弧を削除したこれらすべての言語はどうなりますか? それらはどのようにして本物のプログラミング言語と呼ぶことができますか?

意味をお見せします。 これは、通常の中括弧で囲まれたサンプルコードです。

 public class Squarer { public int Square(int input) { var result = input * input; return result; } public void PrintSquare(int input) { var result = this.Square(input); Console.WriteLine("Input={0}. Result={1}", input, result); } }
      
      







そして、同様のコードがありますが、中括弧はありません。

 type Squarer() = let Square input = let result = input * input result let PrintSquare input = let result = Square input printf "Input=%i. Result=%i" input result
      
      







違いを見てください! 私はあなたのことは知りませんが、2番目の例では、何か重要なものがここに欠けているかのように気になります。

正直に言うと、かっこなしでは少し迷いました。



理由4.明示的な型が見たい



関数型言語の支持者は、型推論によってコードがよりきれいになり、常に型定義でコードが乱雑になるのを防ぐと主張しています。

実際、ところで、型宣言を見たいです。 各パラメーターの正確なタイプがわからないと、恥ずかしい思いをします。 これが、 Javaが私のお気に入りの言語である理由です。

MLに似たコードの関数シグネチャは次のとおりです。 型の定義は必須ではなく、すべてが自動的に表示されます。

 let GroupBy source keySelector = ...
      
      







そして、同様のC#コードの関数シグネチャと、明示的な型定義があります。

 public IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>( IEnumerable<TSource> source, Func<TSource, TKey> keySelector ) ...
      
      







たぶん私は少数派ですが、私は2番目のバージョンがずっと好きです。 関数がIEnumerable<IGrouping<TKey, TSource>>



型を返すことを知ることは重要です。



もちろん、コンパイラーは型チェックを行い、型の不一致を検出すると警告します。 しかし、なぜあなたの頭脳がそれを行うことができるなら、コンパイラーにこれをさせますか?

まあ、ジェネリック、ラムダ、関数を返す関数、およびこれらのすべての新しいものを使用すると、型定義が非常に複雑で混乱しやすくなると思います。 そして、それらを正しく入力することは非常に難しくなります。

しかし、これには簡単な解決策があります。generic'iを使用せず、関数をどこにも渡さないでください。署名がずっと簡単になります。



理由5。バグを修正したい



下手なバグを探すのは好きではありません。 バグが実稼働環境にある場合、これはさらに優れています。修正すると同時にヒーローになるからです。

しかし、静的に型付けされた関数型言語のプログラムでは、バグを許可することははるかに難しいことを読みました。 残念だ。



理由6.デバッガーに住んでいる



ちなみに、バグの修正については、1日の大部分をデバッガーでステップごとにコードを実行することに費やしています。 はい、ユニットテストを使用する必要がありますが、言うより簡単ですか? そうですか?

いずれにせよ、静的に型付けされた関数型言語のコードがコンパイルされると、 通常は機能することは明らかです。

型を適合させるために多くの時間を費やす必要があると言いましたが、これが完了してコードが正常にコンパイルされると、デバッグするものは何もありません。 さて、それの楽しみは何ですか?

この理由は、私を次のように導きます...



理由7。すべての小さなことを考えたくない



タイプを確認し、すべてが正常であることを確認してください。

実際、境界の可能性のあるすべてのケース、入力データの誤りが原因で発生する可能性のあるすべてのエラー、および一般に問題が発生する可能性のあるすべてについて考えることを強いられていると聞きました。 そして、あなたは最初にこれをすべてしなければなりません、あなたはあまりにも怠cannotであり、後でそれをすべて置くことはできません。

私はプログラムを完全に(まあ、ほぼ完全に)前向きなシナリオ(考えられるすべてのエラーが考慮されていない)で動作させ、バグが表示されたときに修正することを好みます。



理由8. nullをチェックしたい



私は非常に忠実に各メソッドでnullチェックを行います 。 それは私に多くの満足を与えます。その結果、私のコードは完全に防弾です。

 void someMethod(SomeClass x) { if (x == null) { throw new NullArgumentException(); } x.doSomething(); }
      
      







ハハ 私は冗談を言っていた。 もちろん、どこにでもヌルチェックを挿入することはできません。そうしないと、実際のプロジェクトを完了できません。

さらに、練習中に、NullPointerExceptionによって引き起こされる深刻な問題に遭遇したのは一度だけです。 そして、問題を見つけることに費やした数週間の間、ビジネスはそれほどお金を失いませんでした。 それで、これがそんなに必要なことであるかどうかはわかりません。



理由9.どこでもデザインパターンを使用している



私は最初にHead First Design Patternsの本でデザインパターンについて読みまし (何らかの理由で「Gang of Four Book」と呼ばれていますが、理由はわかりません)。それ以来、常に問題を解決するために熱心に使用しています。 その後の私のコードは真面目で「エンタープライズ」に見え、これが私のボスに印象的だと思います。

しかし、機能設計のパターンについては言及していません。 Strategy、Abstract Factory、Decorator、Proxyなどを使用せずに何か便利なことをするにはどうすればよいですか?

おそらく、機能的なプログラマーはテンプレートを知らないのでしょうか?



理由10.数学が多すぎる



以下は、二乗和を計算するコードです。 この録音方法は、これらすべての奇妙なキャラクターのために理解するのが難しすぎます。

 ss=: +/ @: *:
      
      







ああ、ごめんなさい! 私は間違っていました、それはJのコードでした

しかし、関数型言語では<*>



>>=



などの奇妙な文字、または「モナド」や「ファンクター」などのわかりにくい概念を使用していると聞きました。

++のような記号のような明らかなもの、そして継承やポリモーフィズムのような軽い概念など、機能的なプログラマーが私が既に知っていることを守れなかった理由がわかりません!



結果。 わからない



あなたは知っています、私はこれを理解していません。 関数型プログラミングの有用性がわかりません。

情報に圧倒されるのではなく、誰かに本当のメリットを1ページで見せてほしいのです。

更新:さて、今、「1ページで知る必要があるすべて」という記事を読みました。 しかし、彼女は私にとって非常に短くてシンプルです。

それと同じように、もう少し深く、生産的に作業 できる ものを探しています。

いいえ、 マニュアルを読んで、 を試して、独自のコードを書くべきだと言ってはいけません。 これをすべて行わずに見たいだけです。

新しいパラダイムを学ぶためだけに、考え方を変えたくありません。



記事に関する著者のコメント
ユーモアに問題がある人のために:この記事を真剣に受け止める必要はありません。



私が誇張またはトロールだと思う人のために。 この記事の内容はすべて、私が読んだことや他の人から個人的に聞いたことに基づいています(ほんの少し誇張して)。 私は彼らの反応に暗示されていることを単に明示した。



また、関数型プログラミングを使用しないことを好む人のために、私がスノブになったり、腐敗したりするつもりはないことも説明します。 人々は好きなツールを使用できます。 そして、関数型言語を使用しない理由はたくさんあります。私が引用したのと同じ理由は、これとは関係ありません。 私はいつもそのような保護的で不合理な「議論」に出くわし、それらを真剣に受け止めるべきではありません。



各アイテムのいくつかの前提条件:



理由1:ファッション。 何回聞いたかは言えません。 コンピュータサイエンスの歴史について少し読んでください。 「私は保守的で、新しいことを学ぶのが好きではありません。 それが、ITでのキャリアを選んだ理由です。」 まあ。



理由2:「コードの行ごとに支払う」。 誰もこれを直接言ったわけではありませんが、たとえばPythonとJavaのような議論を見ると、長くて退屈なコードを書く方が間違いなく快適な人もいます。



理由3:「ブレース」。 中かっこなどではありません。 多くの人々は、中括弧がないとコードが読めなくなると主張し、一般にそれらは添付されています 。 私の視点を示すこの記事へのコメントがあります。



理由4:「明示的な型が大好きです。」 実際のコメントに基づいています。



理由5:「バグの修正が大好き」と理由6:「デバッガーに住んでいます。」 繰り返しますが、誰もこれを直接言っていませんが、静的コード分析ツールの不十分な理解がこれについて語っています。 人々に単体テストを書くのは難しい。 断続的な強化は、この動作で暗黙の役割を果たしていると思います。



理由7:「私はすべてのささいなことを考えたくありません。」 私たちは誰もこれをしません。 だからこそ、怠け者にならないツールを使用すべきです。 それ以外の場合は、 The Daily WTFのストーリーの1つとしてすべてが終了する可能性があります。



理由8:「nullをチェックするのが好きです。」 オプションの型の有用性に関する議論をチェックしてください。まもなく、nullのチェックは問題ではないと言っている人々を見つけるでしょう。



理由9:「どこでもパターンを設計する」。 ほぼ文字通り。 ああ。



理由10:「数学が多すぎる。」 別の一般的な理由、およびある程度同意します( このサイトの私のリクエストを参照)。 しかし、好きかどうかにかかわらず、コンピューターサイエンスの理論的な部分は非常に重要です。 SQLは理論に基づいています。 ラムダは理論に基づいています。 セット、 グラフ暗号化 、その他すべてのアルゴリズムも理論に基づいています。 コンピュータサイエンスに 貢献した数学者の数は膨大です。



SQLを実際に使用し、セットを操作する場合、数学の深い知識は必要ありません。 実際、関数型プログラミングのために学ぶ必要がある「数学」は、OOPのSOLID原則よりもそれほど複雑ではありません。 ただ違うものです。



結果。 関数型プログラミングの学習は複雑であり、コードについての考え方にいくつかの変更が必要であることは知っています。 そのため、私はこのサイトを作成して、好奇心が強く、勉強したい人を支援しています。



そして、何か新しいことを学びたくないのであれば、それも良いことです。



説得力のない議論に基づいて試したことがないという事実を拒否しないでください。そうしないと、 この男のようになっしまいます。




All Articles