変数名の有効範囲 (1/3)


let の 場合

話を let の説明に戻しましょう。
        (let ((var-1  expr-1)
              ....
              (var-n  expr-n))
           body)
では、 body 部の評価の際に現われた変数 var-1, ..., var-n の値は、 let で束縛した時の expr-1, ..., expr-n の値になります。 これは同時に、変数名 var-1 ,..., var-n が有効な範囲(スコープ: scope)を示した言葉でもあります。 つまり、 let 式で用いられた変数名ならびに値との束縛関係は、 その body 部においてのみ有効であるということです。

すこし下の例をみてみましょう。 対象としているvar0の宣言と 他のvar0の宣言が同居しています。 また、var0 を使用している箇所がいくつかあります。

(define var0 10)                    ; global な var0 の定義
(define (foo-callee) var0)          ; var0 をみる関数
(define (foo x)                     ; 関数 foo の中で
    (+ var0                         ; let の外(前)で var0 をみる
       (let ((var0 (* x x))         ; var0 の束縛
	     (var1 (* 2 var0)))     ; 別の let 節の中の var0
	 (+ var0                    ; let の中の var0
	    (foo-callee)            ; 呼ばれた関数の中の var0 
	    (let ((var2 3)) (+ var0 var2)) ; 入れ子 let の中の var0
	    (let ((var0 3)) var0)   ; 入れ子の let (衝突)の中の var0
	    var1))
       var0))                       ; let の外(後)で var0 をみる
一体、 var0が有効な範囲はどこなんでしょう。 実は、その時々の値を表示させることで調べることも
出来ます。 結論から言うと、 var0の変数名が有効なのは、 以下の範囲です。

(define var0 10)
(define (foo-callee) var0)
(define (foo x)
    (+ var0
       (let ((var0 (* x x))
	     (var1 (* 2 var0)))
	 (+ var0
	    (foo-callee)
	    (let ((var2 3)) (+ var0 var2))
	    (let ((var0 3)) var0)
	    var1))
       var0))

99.10.6/ Tomio KAMADA: kamada@cs.kobe-u.ac.jp