純関数とは何ですか？
さて､ 純粋な関数は次のようなものです｡
機能があるんです｡
ですから､ このような機能を持つオブジェクトの箱の代わりに､ 単なる機能として考えてください｡
そして､ 1､ 2､ 3を含むリストを渡すとします｡
この関数にこの入力を与えると､ 純粋な関数に期待されることは､ この入力に何かが起こり､
毎回同じ結果になることです｡
つまり､ これを2倍すると､ 2､ 4､ 6を受け取ることになる｡
さて､ 純関数には2つのルールがある｡
ひとつは､ 同じ入力があれば必ず同じ出力を返すということ｡
つまり､ このリストに1､ 2､ 3を与えるたびに､ 自分が作った関数に与えるのである｡
常に同じ出力が返ってくるはずです｡
だから､ 同じ入力で何百万回とこの関数を実行しても､ 同じ出力になるはずだ｡
そして2点目は､ この関数の考え方は､ 副作用を発生させないことです｡
副作用とは何ですか？
副作用とは､ ある機能が行うことで外界に影響を与えることです｡
例えば､ この関数の中で何かを印刷するとしたら､ それは外部に影響しますよね？
だって､ スクリーンに何かをプリントしているんですから｡
画面は外の世界です｡
例えば､ この関数が別のスコープの外に住んでいる変数を触っていたとしたら､ それは副次的な効果です｡
この概念をもう少し理解するために､ コードを見てみましょう｡
ある関数があって､ この関数が掛け算をするとします｡
リストにすることで
では､ 味方ということにして､ リストにします｡
そして､ この中でやりたいことは､ 項目の上でループすることです｡
リストで
そして､ 各項目を掛け合わせ､ 新しいリストに追加したい｡
そこで､ 空のリストとなる新しいリストを作ってみましょう｡
そしてここでは､ 新しいリスト､ ドットアペンドと言います｡
また､ 項目は2倍にしてください｡
そして最後に､ この関数の最後に､ 新しいリストを返したいのです｡
これをやってみよう｡
2倍して1､ 2､ 3と出して､ プリントアウトしましょうと言ったら｡
ここでは､ その出力を紹介します｡
実行」をクリックすると
2個で6個分？
これは純粋な機能なのでしょうか？
考えてみよう｡
最初のルールは､ 同じ入力があれば､ それは1､ 2､ 3である｡
常に同じ出力が返されます｡
何度実行しても､ 同じ出力が出る｡
というわけで､ 一次試験は合格｡
2回目のテストはどうですか？
副作用がないこと｡
副作用はないのでしょうか？
これは､ 外界の何かに触れているのでしょうか？
考えてみてください｡
いいえ､ そんなことはありません｡
そうですね｡
この機能には､ 外界のことは一切関係ありません｡
なぜなら､ この中にすべてが含まれているからです｡
例えば､ ここにprintがあるのではなく､ 単にprintがあるとします｡
そして､ ここにも｡
実行」をクリックすると
同じ出力が得られます｡
しかし､ これには副作用があるのでしょうか？
まあ､ そうなんですけどね｡
print文という外の世界と対話するのです｡
print文は､ このマシンが持っているどんなディスプレイにも印刷するんだ､ ということを教えてくれる｡
私たちの場合､ ここに印刷されるのですが､ こちら側で画面とやり取りをするので､ print文が何をするのかよくわかりません｡
だから､ これ｡
副作用がある｡
私たちは印刷にコントロールを与えていますが､ 印刷が何をするかはわかりません｡
もうひとつ､ 例を挙げましょう｡
ここで新しいリストを作成し､ 実際に外部で定義するとしたら､ こういうことでしょうか｡
そうそう｡
このような新しいリストができるように｡
実行」をクリックすると
今でも2個で6個になるんですよ｡
しかし､ これには副作用があるのでしょうか？
まあ､ そうなんですけどね｡
外の世界と交流する｡
そして､ この関数の世界の外側にあるもの､ それはスコープであることを忘れてはならない｡
この新しいリストと相互作用するんだ｡
この新しいリストに開きます｡
ですから､ もしプログラマーがやってきて､ この関数を実行する前に､ 新しいリストと言うことにしたのかもしれません｡
それを空文字列に変更するのです｡
さて､ この関数を実行すると｡
この新しいリストが文字列オブジェクトであるため､ エラーが発生します｡
つまり､ この関数の外側の世界に住む新しいリストは､ 他の開発者やプログラムによって変更される可能性があり､
我々はそれを知ることができたはずです｡
そして､ この関数を実行すると､ エラーが発生するのです｡
副作用があるんです｡
だから､ 理想は機能を封じ込めることなんです｡
なぜなら､ おわかりのように､ 私たちがここに何か間違ったことを書かない限り､ 私たちのコードにバグやエラーが発生することはないからです｡
しかし､ 外界のことは気にしないので､ インプットとして与えるものはすべて必ず良いアウトプットを生むので､
純粋なものになるのです｡
さて､ なぜこのような強力なコンセプトがあるのか､ 職場での経験がないとなかなか理解できないでしょう｡
ただ､ これだけは言っておきたいのですが､ 純粋な機能がある場合｡
バグが少ないコードになり､ コードのテストもしやすくなります｡
コードも全体的に理解しやすくなります｡
コードの異なる部分が互いに触れ合い､ 影響を及ぼし合うことがないため､
プログラマーとしての生活が非常に楽になるのです｡
だから､ このピュアファンクションという考え方は､ 本当に重要なんです｡
ただ､ ここからひとつだけ受け取ってほしいのは､ 純関数は絶対的なものというより､ ガイドラインのようなものだということです｡
なぜなら､ もし関数が外の世界に全く影響を及ぼさないのであれば､ プログラムが存在しないことになるからです｡
モノを展示することができなくなりますからね｡
ゲームのプロファイルなども保存できなくなります｡
だから､ どこにでも純粋な機能を持たせることは不可能なんです｡
しかし､ できるときに､ できる場所で､ 関数型プログラミングは､ あなたの関数が良いものであることを教えてくれるのです｡
純粋な関数を作るようにし､ 純粋でない関数は､ コードにバグがあったときにいつでも呼び出せるような､
外の世界と相互作用するようなものだけにする｡
なぜなら､ このような純粋な機能では､ ほとんどの場合､ バグが発生するからです｡
関数型プログラミングの概念を確定させるために
例えば､ これが関数型プログラミングの前のビデオで見たウィザードだとしたら､ ウィザードオブジェクトを持つことになります｡
あるいは､ 名前のあるWizard辞書｡
仮にマーリンとしましょう｡
そして､ パワー｡
50のうち｡
そして､ これらをクラスに収めるのではなく､ attackのような異なるメソッドを用意します｡
そして､ これは方法ではないでしょう｡
クラスの中に住んでいないので､ 関数になるのでしょう｡
関数型プログラミングでは
データと機能を一緒にする必要はない､ 分けて考えよう､ と｡
渡すことができる純粋な関数を作ってみよう｡
キャラクターみたいなものなら何でもいいんです｡
このように､ この2つを分けて考えることで､ 純粋な関数に集中でき､ データに集中できるのです｡
そこに差があるんですね｡
結局のところ､ 私たちのコードをきれいに保ち､ コードのバグを回避しようとすることがすべてなのです｡
プログラマーがいつも抱えている大きな問題｡
つまり､ 考え方が違うだけなんです｡
次の動画でもう少し勉強してみましょう｡