yas@is.tsukuba.ac.jp (Yasushi Shinjo) writes:

> > * late bindingではないが、関数の再定義(二重定義)を許す言語の例
> >    … これまで話題になった再定義とはちょっと違うかも知れませんが、
> >    MLの関数名と実体の対応はコンパイル時に完全に決まります。同じ名前の
> >    関数が2つ定義されると、『それ以後の呼び出しでは』新しい定義が参照さ
> >    れます。すでに古い定義を参照してコンパイルされた部分には影響しません。
> 
> 再帰呼出しは、どうなるのですか? 単純なものでなくて、相互に
> 呼び合うものなどです。

その場合は、複数の名前を「同時に」定義しなければなりません。

    fun even 0 = true
      | even n = odd (n-1)
    and odd 0 = false
      | odd n = even (n-1)

MLのfunという構文は、おおむねSchemeの(letrec ((name (lambda ...にあたる
ものです。

Lisperの言葉で言えば、同じ環境に複数の名前が定義され、それらの名前が束
縛される値の式もまた、その同じ環境で評価されます。

> Forth は、late binding ではないのですが、再定義できます。同
> じ名前の手続きを呼ぶと、古いものに対して stacking されます。
> 再帰はできません。たとえば、

SunのROMモニタにはrecというwordがあったような。

> PostScript は再帰はできたと思いますが、showpage を再定義して 
> n-up にしたりしてますね。

PostScriptでは「辞書スタック」が環境に当たります。同じ辞書に複数の名前
を定義すれば、相互再帰ができますね。辞書は書き換え可能ですから、定義を
上書きできます。また、辞書をプッシュして名前を定義すると、上書きでなく
名前を一時的に隠す(shadowする)こともできます。

                                前田敦司