< Chaton-Twitter bridge | トップレベル式 >
2009/10/18
begin
ここで思ったのだが、Lisp ではなんで prog1 や progn (Scheme なら begin) は関数じゃないんだっけ? 引数の評価順序が決まってないから?
では、引数の評価順序を決めてしまえば普通の関数にしていい?
効率?
ちょっと考えてみたんだけど、順序と効率以外にSchemeの場合、次の点が問題になりそうだ。
- beginの途中の式には、「値を返さない」式 (0個の値を返す式) が許される。 また、beginの最後の式は複数の値を返すかもしれない。関数にしてしまうと、 すべて一つの値を返さなければならなくなる。 (prog1に相当するGaucheのbegin0も、最初の式で複数の値を返すことができる)。
- beginフォーム自体が末尾式の場合、beginの最後の式は末尾コンテキストで
評価されなければならない。関数にしてしまうと引数評価は末尾コンテキストにならない。
例えば次の式が末尾再帰にならない:
(let loop () (begin ... (loop))
begin0の場合はこれは関係ない。 - beginは定義式を含むことが許されてて、 これらの定義式はbeginが現れた位置にspliceされる。 複数の定義式へと展開されるマクロを書くため。
CLの場合は末尾再帰が要求されてないし、多値の受け取りの条件も緩いので、 問題になるのはprognの最後の式が2つ以上の値を返す場合のみかな?
まあ現実問題として、(prog1 exp0 exp1 ... exp100) なんて式でprog1が 関数だと、100個分の結果を必要もないのにどっかに貯めておくなんてもったいない って思っちゃうので、実用上は効率が一番気になるかもしれん。
Tags: Programming, Scheme, Lisp