さて、次はクロージャと高階関数を組み合わせてみましょう。
クロージャと高階関数についても組み合わせて考えることは簡単です。
クロージャは引数以外の変数を実行時の環境ではなく、自身が定義された環境(静的スコープ)において解決することを特徴とするでした。 つまり関数内のローカル変数の状態が保存されました。
このクロージャと高階関数を組み合わせると、関数内のローカル変数を操作する関数をその関数の外の関数型の変数から呼び出せるようになります。
次の例を見てください。
// sample program for enhanced PL/0 var INC:func, DEC:func, DOUBLE:func, PR:func; int: function counter(); begin var n:int; int: function Inc(); begin n = n + 1; print n; end int: function Dec(); begin n = n - 1; print n; end int: function Double(); begin n = n * 2; print n; end int: function Pr(); begin print n; end n = 0; INC = Inc; DEC = Dec; DOUBLE = Double; PR = Pr; end begin counter(); PR(); INC(); INC(); INC(); INC(); INC(); INC(); INC(); DEC(); DEC(); DEC(); INC(); INC(); DOUBLE(); PR(); end
関数counterの中で、変数nとInc, Dec, Double, Pr関数をローカル関数として定義しています。 そして、変数nは0に、外部の変数INCに関数Inc, 変数DECに関数Dec、変数DOUBLEに関数Double、および変数PRに関数Prを設定しています。
これにより、変数nは関数counter内のクロージャ変数となります。
変数INC、DEC、DOUBLE、PRには、関数counter内のローカル定義関数が高階関数として設定され、counter関数の外からも関数として呼び出されるようになりました。
このようにクロージャと高階関数と組み合わせるとあたかも関数をオブジェクト指向のオブジェクトのように扱うことができるようになるのです。
六式言語も五式言語と同様で、ベースに四式言語である高階関数をサポートするプログラミング言語を使いましょう。これは手続き言語に高階関数を実現したものでした。
この四式言語に、クロージャをサポートする言語である三式言語の改造点を加えます。
- C言語への出力のローカル変数の定義にstaticを付ける
これにより、関数内の変数が関数の実行終了後も値が保持し続けます。
さらにこの修正に加えてこれはオマケですが、六式言語では配列の定義もできるようにしましょう。