プログラミングパラダイム
関数型プログラミングを理解する上で、命令型プログラミング出身者にとって最大のハードルのひとつは、考え方の転換です。命令型プログラムは どうやるのか を記述するのに対し、宣言型プログラムは 何をするのか を記述します。これを示すために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 | 結果 |
---|---|---|
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 |