For Development HEAD DRAFTSearch (procedure/syntax/module):

11.30 srfi.154 - 第一級の動的エクステント

Module: 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-portprint-errorが定義された時点の 値を返します:

(define print-error
  (dynamic-lambda (msg) (display msg (current-error-port))))
Function: current-dynamic-extent

[SRFI-154]{srfi.154} 現在の動的環境を具象化した動的エクステントオブジェクトを返します。

Function: dynamic-extent? obj

[SRFI-154]{srfi.154} objが動的エクステントオブジェクトの時のみ#tを返します。

Function: with-dynamic-extent dynext thunk

[SRFI-154]{srfi.154} 動的環境を動的エクステントdynextで置き換えた状態で thunkを呼びます。thunkが返した値が戻り値となります。

Macro: dynamic-lambda formals body …

[SRFI-154]{srfi.154} lambdaのように振る舞いますが、レキシカルな環境だけでなく、 評価時の動的環境も捕捉します。手続きを返します。

註: dynamic-lambdaは最後のbodyの実行が終わった後で動的環境を 戻さなければならないので、dynamic-lambdaで作られた手続きが末尾呼び出し されたとしても、bodyの末尾式は末尾呼び出しにはなりません。



For Development HEAD DRAFTSearch (procedure/syntax/module):
DRAFT