例を考えてみましょう: 電球をつけたり消したりしたいです。C では、次のように書くことができます。
struct lightbulb {
int is_turned_on;
/* from 1 to 10 */
int light_intensity;
};
電球をオンまたはオフにするときはいつでも、1 (最も暗い) から 10 (最も明るい) にis_turned_on
設定することで、1 に変更し、明るさを変更します。light_intensity
関数型プログラミングで同じことを行うにはどうすればよいですか? ON
これらの値を保持するリストを作成し、関数を作成しOFF
て電球をオン/オフにし、電球の光の強度を返す関数を作成する必要があると思います。関数が呼び出されるたびに、新しい電球が返されます。
(defun turn-on()
'(1 0))
(defun turn-off()
'(0 0))
(defun light-intensity (x)
`(0 ,(eval x)))
light-intensity のような関数は、線形関数に似た連続関数であることがわかります。x
xごとに同じ引数を何度渡しても、同じ結果に評価されます。各関数の結果は、異なる状態の新しい電球です。
問題は、どうすれば状態を永続化できるかということです。明らかに、変数を介してメモリのどこかに保存する必要があります。
更新: c2 Wiki - Functional Programmingを通じて上記の質問に対する回答を見つけました
データ項目はどのように保持されますか?
スタック上。シーケンシャル バッチ プログラムでは、データは最上位関数で初期化および変換されます。サーバーのような長期間存続するプログラムでは、最上位のループ関数が再帰的に呼び出され、ある呼び出しから次の呼び出しにグローバル状態が渡されます。
また、関数が呼び出されるたびに新しいオブジェクト (リスト) を作成する必要があります。以前の古いオブジェクトを破棄するにはどうすればよいですか?
defparameter
andを介して変数を変更する方が効率的で簡単ではありませんsetf
か? それが電球ではなく、より多くの情報を持つより複雑なオブジェクトであると想像してみてください。これを関数としてモデル化するにはどうすればよいですか?