srfi.154
- 第一級の動的エクステント ¶このモジュールは、動的環境を簡単に取り出す手段を提供します。
call/cc
によって捕捉される継続は、制御フローと同時に動的環境を保持しますが、
時には動的環境だけが欲しい場合があります。
動的エクステントは、具象化された動的環境です。
例で見てみましょう。メッセージをエラー出力に出したいので、
こんなprint-error
を書いたとします:
(define print-error (lambda (msg) (display msg (current-error-port))))
ところで、print-error
が呼ばれた時点で現在のエラー出力ポートが置き換えられていたら、
出力先は変わります。もちろん、そのためのcurrent-error-port
なのですから、
これは想定された動作です。
(call-with-output-string (^p (with-error-to-port p (^[] (print-error "abc\n"))))) ⇒ "abc\n"
けれども、print-error
が定義された時点でのエラー出力ポートを常に使いたい
場合はどうすれば良いでしょうか。ひとつの方法は、定義時のエラー出力ポートの
動的な値を保存しておくことです:
(define print-error (let1 eport (current-error-port) (lambda (msg) (display msg eport))))
しかし、これは捕捉したい動的な値が増えればややこしくなりますし、
print-error
が自分の触れない箇所で定義されていて書き換えられない場合も
面倒です。
dynamic-lambda
は、レキシカルな環境だけでなくそれが評価された時点の
動的環境をも捕捉することでこの問題を解決します。
次の例では、current-error-port
はprint-error
が定義された時点の
値を返します:
(define print-error (dynamic-lambda (msg) (display msg (current-error-port))))
[SRFI-154]{srfi.154
}
現在の動的環境を具象化した動的エクステントオブジェクトを返します。
[SRFI-154]{srfi.154
}
objが動的エクステントオブジェクトの時のみ#t
を返します。
[SRFI-154]{srfi.154
}
動的環境を動的エクステントdynextで置き換えた状態で
thunkを呼びます。thunkが返した値が戻り値となります。
[SRFI-154]{srfi.154
}
lambda
のように振る舞いますが、レキシカルな環境だけでなく、
評価時の動的環境も捕捉します。手続きを返します。
註: dynamic-lambda
は最後のbodyの実行が終わった後で動的環境を
戻さなければならないので、dynamic-lambda
で作られた手続きが末尾呼び出し
されたとしても、bodyの末尾式は末尾呼び出しにはなりません。