プログラミングパラダイム
命令型の背景から関数型プログラムを理解しようとするとき、最大の障壁の1つは考え方の変化です。命令型プログラムは、何かを行う方法を記述するのに対し、宣言型プログラムは何を行うかを記述します。これを示すために、1から10までの数値を合計してみましょう。
命令型
#![allow(unused)]
fn main() {
let mut sum = 0;
for i in 1..11 {
sum += i;
}
println!("{sum}");
}
命令型プログラムでは、何が起きているのかを理解するために、私たちがコンパイラの役をしなければなりません。ここでは、0 の sum から始めます。次に、1から10までの範囲を反復処理します。ループを1回通るたびに、その範囲内の対応する値を加算します。その後、それを出力します。
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 | 結果 |
|---|---|---|
| 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 |