あなたは関数型プログラマになりたい(パート6)

関数型プログラミングの概念を理解するための最初の一歩を踏み出すことは、最も重要で、時には最も困難な手順です。しかし、そうである必要はありません。正しい視点ではありません。

前のパート:パート1、パート2、パート3、パート4、パート5

それで?

この素晴らしい新機能をすべて習得したので、おそらく「今は何?日常のプログラミングでこれをどのように使用できますか?」

場合によります。 ElmやHaskellなどの純粋な関数型言語でプログラミングできる場合は、これらのアイデアをすべて活用できます。そして、これらの言語はそうすることを簡単にします。

多くの人がそうであるように、Javascriptのような命令型言語でしかプログラミングできない場合でも、学んだことの多くを使用できますが、さらに多くの規律が必要になります。

機能的なJavaScript

Javascriptには、より機能的な方法でプログラミングできる多くの機能があります。純粋ではありませんが、言語には不変性があり、ライブラリを使用すればさらに不変になります。

理想的ではありませんが、使用する必要がある場合は、関数型言語の利点をいくつか得てみませんか?

不変性

最初に考慮すべきことは不変性です。 ES2015、またはES6と呼ばれるES6には、constと呼ばれる新しいキーワードがあります。これは、変数が設定されるとリセットできないことを意味します。

const a = 1;
a = 2; //これにより、Chrome、Firefox、またはNodeでTypeErrorがスローされます
       //ただし、Safariではない(2016年10月頃)

ここでaは定数として定義されているため、一度設定すると変更できません。これが、a = 2が例外をスローする理由です(Safariを除く)。

Javascriptのconstの問題は、十分に行かないことです。次の例は、その制限を示しています。

const a = {
    x:1、
    y:2
};
a.x = 2; // 例外なし!
a = {}; //これはTypeErrorをスローします

a.x = 2が例外をスローしないことに注意してください。 constキーワードで不変なのは変数aだけです。が指すものはすべて変異させることができます。

これは、Javascriptを非常に良くしたので、非常に残念です。

それでは、Javascriptで不変性をどのように得るのでしょうか?

残念ながら、これはImmutable.jsと呼ばれるライブラリを介してのみ可能です。これにより、より良い不変性が得られる可能性がありますが、悲しいことに、コードがJavascriptよりもJavaのように見えるようになります。

カレーと作曲

このシリーズの前半で、カリー化された関数の作成方法を学びました。より複雑な例は次のとおりです。

const f = a => b => c => d => a + b + c + d

カレー部分を手書きで書かなければならないことに注意してください。

fを呼び出すには、次のように記述する必要があります。

console.log(f(1)(2)(3)(4)); // 10を印刷します

しかし、それはLispプログラマーを泣かせるのに十分な括弧です。

このプロセスを容易にする多くのライブラリがあります。私のお気に入りはラムダです。

Ramdaを使用して、次のように記述できます。

const f = R.curry((a、b、c、d)=> a + b + c + d);
console.log(f(1、2、3、4)); // 10を印刷します
console.log(f(1、2)(3、4)); // 10も出力します
console.log(f(1)(2)(3、4)); // 10も出力します

関数の定義はそれほど良くありませんが、これらすべての括弧の必要性を排除しました。 fを呼び出すたびに、必要な数だけパラメーターを適用できることに注意してください。

Ramdaを使用して、パート3およびパート4のmult5AfterAdd10関数を書き換えることができます。

const add = R.curry((x、y)=> x + y);
const mult5 = value => value * 5;
const mult5AfterAdd10 = R.compose(mult5、add(10));

Ramdaには、このようなことを行うためのヘルパー関数がたくさんあることがわかります。 R.addとR.multiplyは、より少ないコードを書くことができることを意味します。

const mult5AfterAdd10 = R.compose(R.multiply(5)、R.add(10));

マップ、フィルター、および削減

Ramdaには独自のバージョンのmap、filter、reduceもあります。これらの関数はバニラJavascriptのArray.prototypeに存在しますが、Ramdaのバージョンはカリー化されています。

const isOdd = R.flip(R.modulo)(2);
const onlyOdd = R.filter(isOdd);
const isEven = R.complement(isOdd);
const onlyEven = R.filter(isEven);
const番号= [1、2、3、4、5、6、7、8];
console.log(onlyEven(numbers)); // [2、4、6、8]を出力します
console.log(onlyOdd(numbers)); // [1、3、5、7]を出力します

R.moduloは2つのパラメーターを取ります。最初は配当(分割されるもの)であり、2番目は除数(分割されるもの)です。

isOdd関数は、2で割った余りだけです。0の余りは、奇数ではなく偽であり、1の余りは、奇数です。除数として2を指定できるように、モジュロの最初と2番目のパラメーターを反転しました。

isEven関数は、isOddの単なる補完です。

onlyOdd関数は、isOddの述語(ブール値を返す関数)を持つフィルター関数です。実行する前に、最後のパラメーターである数値のリストを待っています。

onlyEven関数は、述語としてisEvenを使用するフィルターです。

onlyEvenとonlyOddに数値を渡すと、isEvenとisOddが最終パラメーターを取得し、最終的に実行して期待する数値を返します。

Javascriptの欠点

これまでにJavascriptを取得したすべてのライブラリと言語の機能強化により、すべての人々にとってすべてのものになろうとしている命令型言語であるという事実に依然として悩まされています。

ほとんどのフロントエンド開発者は、ブラウザでJavascriptを使用するのにこだわっています。これは、これが長い間唯一の選択肢であったためです。しかし、多くの開発者は現在、Javascriptを直接記述することから遠ざかっています。

代わりに、彼らは別の言語で記述し、Javascriptにコンパイル、またはより正確にトランスコンパイルしています。

CoffeeScriptはこれらの言語の最初の1つでした。そして今、TypescriptがAngular 2に採用されました。BabelはJavascriptのトランスパイラーと考えることもできます。

このアプローチを実動で使用する人が増えています。

しかし、これらの言語はJavascriptで始まり、ほんの少しだけ改善されました。どうにかして、純粋関数型言語からJavascriptに移行してみませんか?

エルム

このシリーズでは、関数型プログラミングの理解を助けるためにElmを調べました。

しかし、エルムとは何ですか?そして、どうすればそれを使用できますか?

ElmはJavascriptにコンパイルされる純粋な関数型言語であり、これを使用してElmアーキテクチャ(別名TEA)を使用してWebアプリケーションを作成できます(このアーキテクチャはReduxの開発者に影響を与えました)。

Elmプログラムには、ランタイムエラーはありません。

ElmはNoRedInkなどの企業で生産に使用されており、Elmの作成者であるEvan Czaplikiが現在働いています(以前はPreziで働いていました)。

詳細については、NoRedInkのRichard FeldmanとElmの伝道者によるこの講演、6か月間のElmの制作を参照してください。

JavascriptをすべてElmに置き換える必要がありますか?

いいえ。部品を段階的に交換できます。詳細については、このブログエントリ「Elm at Workの使用方法」を参照してください。

エルムを学ぶ理由

  1. 純粋関数型言語でのプログラミングは、制限と解放の両方を行います。それはあなたができることを制限します(主に自分を足から撃つことを防ぐことによって)が、同時にすべてのElmプログラムが機能的リアクティブモデルであるElm Architectureに従うので、バグや悪い設計決定からあなたを解放します。
  2. 関数型プログラミングは、より優れたプログラマーになります。この記事のアイデアは、氷山の一角にすぎません。プログラムのサイズがどのように縮小し、安定性が向上するかを実際に理解するには、実際にそれらを見る必要があります。
  3. Javascriptは最初は10日間で構築され、その後20年間パッチを適用して、機能的でオブジェクト指向で完全に命令的なプログラミング言語になりました。
    Elmは、Haskellコミュニティでの過去30年間の研究で学んだことを使用して設計されました。Haskellコミュニティは、数学とコンピューターサイエンスの数十年の研究から得たものです。
    Elm Architecture(TEA)は、長年にわたって設計および改良され、機能的リアクティブプログラミングに関するEvanの論文の結果です。時間と空間の制御を見て、この設計の定式化に至った思考のレベルを評価してください。
  4. Elmは、フロントエンドWeb開発者向けに設計されています。彼らの生活を楽にすることを目的としています。 Let's Be Mainstreamを見て、この目標をよりよく理解してください。

未来

未来がどうなるかを知ることは不可能ですが、経験に基づいた推測を行うことができます。ここに私のものがあります:

Javascriptにコンパイルされる言語への明確な動きがあります。
40年以上にわたって存在していた関数型プログラミングのアイデアは、現在のソフトウェアの複雑さの問題を解決するために再発見されます。
ハードウェアの状態、例えばギガバイトの安価なメモリと高速プロセッサにより、機能的なテクニックが実行可能になります。
CPUは高速になりませんが、コアの数は増え続けます。
可変状態は、複雑なシステムにおける最大の問題の1つとして認識されます。

このシリーズの記事を書いたのは、関数型プログラミングは未来だと信じているからであり、過去数年にわたって学習に苦労したからです(まだ学習中です)。

私の目標は、他の人がこれらの概念を私よりも簡単かつ迅速に学習できるように支援し、他の人がより良いプログラマーになり、将来より市場性のあるキャリアを持つことができるようにすることです。

Elmが将来巨大な言語になるという私の予測が間違っていたとしても、Functional ProgrammingとElmは未来が何であれ軌道に乗っていると確信をもって言うことができます。

このシリーズを読んだ後、あなたが自分の能力とこれらの概念の理解に自信を持つことを願っています。

今後のご活躍をお祈りしております。

これが気に入ったら、下のをクリックして、他の人がこれを中に表示するようにします。

ElmのFunctional Programmingを使用してWebアプリの開発を学び、支援するWeb開発者のコ​​ミュニティに参加したい場合は、FacebookグループのLearn Elm Programming https://www.facebook.com/groups/learnelm/をご覧ください。

私のTwitter:@cscalfani