プログラミングパラダイム
命令型プログラミングの経験がある人が関数型プログラムを理解する上で最も大きなハードルの一つは、考え方の転換です。命令型プログラムはどのようにやるかを記述するのに対し、宣言型プログラムは何をするかを記述します。 1から10までの数値を合計する例を見てみましょう。
命令型
#![allow(unused)] fn main() { let mut sum = 0; for i in 1..11 { sum += i; } println!("{sum}"); }
命令型プログラムでは、何が起こっているかを理解するためにコンパイラの役割を演じる必要があります。
ここでは、sumを0から始めます。次に、1から10までの範囲を反復処理します。ループを通過するたびに、範囲内の対応する値を加算します。
そして、それを出力します。
i | sum |
|---|---|
| 1 | 1 |
| 2 | 3 |
| 3 | 6 |
| 4 | 10 |
| 5 | 15 |
| 6 | 21 |
| 7 | 28 |
| 8 | 36 |
| 9 | 45 |
| 10 | 55 |
これは、私たちの多くがプログラミングを始める方法です。プログラムは一連のステップであることを学びます。
宣言型
#![allow(unused)] fn main() { println!("{}", (1..11).fold(0, |a, b| a + b)); }
わあ!これは本当に違いますね!何が起こっているのでしょうか?宣言型プログラムでは、どのようにやるかではなく、何をするかを記述することを思い出してください。foldは関数を
合成する関数です。この名前はHaskellの慣例から来ています。
ここでは、加算の関数(このクロージャ:|a, b| a + b)を1から10までの範囲と合成しています。0は開始点なので、最初はaが0です。bは範囲の最初の要素である1です。0 + 1 = 1が結果です。そして、a = 1、b = 2で再びfoldし、1 + 2 = 3が次の結果になります。このプロセスは範囲の最後の要素10に到達するまで続きます。
a | b | result |
|---|---|---|
| 0 | 1 | 1 |
| 1 | 2 | 3 |
| 3 | 3 | 6 |
| 6 | 4 | 10 |
| 10 | 5 | 15 |
| 15 | 6 | 21 |
| 21 | 7 | 28 |
| 28 | 8 | 36 |
| 36 | 9 | 45 |
| 45 | 10 | 55 |