In article <20020213081859.19fa53a2.hayase / hcn.zaq.ne.jp>,
  早瀬 康裕 <hayase / hcn.zaq.ne.jp> writes:

> # gccでは最適化オプションをつけないとuninitialized variableを検出できない
> (エラー・警告なし)

たしか、最適化しない場合は flow analysis をしないからだったかな。

> % sml
> Standard ML of New Jersey, Version 110.0.3, January 30, 1998 [CM; autoload enabled]
> - val x=x;
> stdIn:17.7 Error: unbound variable or constructor: x

val の右辺は x のスコープに入ってないからですね。SML の構文はよく覚え
てないんですが、再帰的なものを定義する構文だとどうでしょうか。rec をつ
けるんだっけか?

> emacs lips(xemacs)
> 
> (let '(x x) x) 
> Symbol's value as variable is void: x 

(let ((x x)) x) だとすれば SML と理由は同じです。

> SML/NJやelispは、動的スコープ(というか環境?)なので、代入…じゃなくて定義前
> に変数の値を使うことは出来ませんね。(あ、setqは代入でいいのか…)

elisp が動的スコープであることには同意しますが、SML/NJ もそうといわれ
ると首をかしげざるを得ません。ここでいう動的スコープってなんですか?

> ということで私の期待に反し(?)、CとJavaでは、初期値計算の前に名前が登録され
> るようです。コンパイラの処理を考えてみれば、型と変数名が現れた時点でスコー
> プに登録するのが自然なので、ある意味当然の結果かも知れません。
> 
> # Javaはともかく、Cは仕様書(またはそれに準ずるもの)に当るのが正しいと思う
> # のですが、手をぬいてしまいました。

C はたしか変数宣言で変数名が現れた箇所の後ならどこでも名前を使って良かっ
たような気がします。少なくとも sizeof とか & とかは。

> 静的スコープを持つが、宣言しようとしている変数を初期値計算に使えない言語
> をご存じの方がいらっしゃいましたら、教えていただけると嬉しいです。

ここでいう静的スコープが私の思っているところの static scope/lexical
scope であるとすれば ML も含めていくつか思い当たるものがあります。とい
うか、eager な関数型言語なら、実装はともかく、概念的には禁止されてるは
ずなんじゃないかと思いますが。変数の値が初期値の計算中とそれ以降で変化
することは参照透明性を破ることになるので。

Scheme の let のように初期値を与える式がそもそも宣言している変数のスコー
プに入っていないやつはもちろん、letrec のようにスコープに入っていても
たしか初期値が求まる前に参照するのは禁止されていた覚えがあります。
(R4RS を読んだのはかなり前なので正確なところは覚えていませんが。)

他には Objective Caml も同様で、

# let a = a;;
Unbound value a
# let rec b = b;;
This kind of expression is not allowed as right-hand side of `let rec'

というようにどっちでも禁止です。
`This kind of expression' というのはエラーメッセージとして最低だと思い
ますが、結局 b の値が求まる前に b を使うことは許されていないということ
です。

逆に lazy なやつだと少々状況は違ってきて、例えば Haskell なら
  a = 1:a
なんてこともできるわけですが。まぁ、このへんになると初期値計算とは何か
というのをはっきりさせないと使えるとも使えないともいえないかな。

というあたりが私の認識ですが。
-- 
[田中 哲][たなか あきら][Tanaka Akira]
「ふえろ! わかめちゃん作戦です$(C⊇」(Little Worker, 桂遊生丸)