ELispが何故末尾再帰を実装していないか (2)
実装していないんじゃない。出来ないんだ。
「EmacsLispはdynamic scopeを持つ言語である。dynamic scopeの実装方法は2つ有るが、いずれにせよあるブロックを評価し終わった段階でstackからsymbolの値を復帰させる必要が有る。だから、以下のような末尾再帰を実現する評価ループを適応する事が出来ない。」
eval_loop: if (SYMBOLP(obj)) { obj = scm_symbol_value(obj, state.env); } else if (CONSP(obj)) { obj = call(CAR(obj), CDR(obj), &state, SCM_VALTYPE_NEED_EVAL); if (state.ret_type == SCM_VALTYPE_NEED_EVAL) goto eval_loop; }
という事かなぁ。”動的スコープのこうこうこういう性質が末尾再帰のこの定義に反するから”とかいう強い理由付けが欲しい所だが。
Emacs Lispマニュアルを眺めていると、"Emacs Lisp uses dynamic scoping because simple implementations of lexical scoping are slow. "の件が目に付く。まぁ確かにlexical scopeの場合はsymbolの値を得る度にenvironmentを探索しなきゃならんからなぁ。shallow bindingなdynamic scope実装だとsymbolのvalue cellを参照するだけで済むのか。なるほどねぇ、RMSはこの辺りのトレードオフを考えたんだな。ELispの設計意図をちょいと垣間見た。