クロージャ

クロージャとは

クロージャとは手続きと環境(変数の束縛等、実行時の状態)の組みです。

これだけではわからないので、例を挙げます。

「foo を 「(x) 「x を 表示」 の 仕事」
        と 定義します」

「10.0 foo」
     ---> 10.0

一つ目の文の

「(x) 「x を 表示」 の 仕事」

によってクロージャが作製されます。 リストの先頭がクロージャが受け取る引数のシンボルで、 クロージャが評価されるときに与えられた引数がこのシンボルに束縛されます。 2番目以降、最後のlambda(とそのエイリアスである"仕事")を除いた部分までが 順に実行されます。 この例の場合、与えられた引数をシンボルxに束縛し、表示を行う クロージャが作製されます。

このクロージャがfooというシンボルに束縛されます。

二つ目の文でクロージャが使用されます。 引数はクロージャの前に置きます。

クロージャのスコープ

クロージャはそれが作製された時点の変数の束縛を保持しています。

「n を 1 と 定義 します」

「加算器生成 を 「(n) 「(x) 「n x +」 の 仕事」 の 仕事」 と 定義 します」

「3加算器 を 「3 加算器生成」 と 定義します」

「「2 3加算器」 表示」
     ---> 5.0

「n を 1 に セット します」

「「2 3加算器」 表示」
     ---> 5.0

加算器生成を定義する文では

「(x) 「n x +」 の 仕事」

を返すクロージャを作製しています。

ここでxはこのクロージャが評価されるときに与えられる引数ですが、 nはこのクロージャが作製された時点の束縛が使用されます。

「3加算器 を 「3 加算器生成」 と 定義します」

この部分で加算器生成が評価されることによって 上記のクロージャが作製されます。 加算器生成には3が与えられますので、nには3が束縛されることになります。 結局、3加算器に束縛されるクロージャ中のnには3が束縛されていることになります。

このnはクロージャが束縛されていた時点の束縛が使用されますので、 セットでnの束縛を変化させても変化しません。