[Prev]    [ Up ]    [Next]

変数のスコープ --- 局所変数・大域変数

関数の定義

	> (define (succ x) (+ x 1))
	succ
の引数(パラメータ)に使われる変数xは、その関数の内部でのみ有効である. このような変数を局所変数という.
	> (succ 3)
によって、関数が呼び出されると、局所変数xに3が割当てられる. その後,本体(+ x 1)が,このxの値を使って評価される. この局所変数は,関数が評価される際に一時的に用意されるものであって,関数の評価が終わった後にその値を参照することはできない.
	> (succ 3)
	4
	x
	> x
	==> error ;; xは定義されていない
この関数succとは別に
	> (define (pred x) (- x 1))
が定義されていたとしても,関数pred内の局所変数xと関数succの局所変数xは無関係である.
	;; (x - 1)(x + 1)
	> (define (foo x) (* (pred x) (succ x))
	foo
	> (foo 5)
	;; (* (pred 5) (succ 5))
	;; (* (- 5 1) (succ 5))
	;; (* 4 (+ 5 1))
	;; (* 4 6)
	24

一方,Scheme処理系のプロンプトから直接に

	> (define x 100)
	x
のように定義した場合,この定義は,いつでも参照可能である.このような変数を大域変数という.
	> x
	100
	> (define (f y) (* x y))
	f
	> (f 2)
	200
	> (set! x -200)
	-200
	> (f 2)
	-400	

ある変数が参照できる範囲をその変数のスコープという. 関数の引数のスコープは,その関数の中のみである. 大域変数は,常に有効であり,そのスコープは全域である. ある大域変数と同じ名前の局所変数があったとき,局所変数のスコープの範囲においては,局所変数の値が有効になる. 局所変数のスコープを抜けた後は,大域変数が有効になる. 大域変数の値は,局所変数の値には影響されない.

	> (define (bar x) (set! x (succ x)) x)
	bar
	> (define x 100)
	x
	> (bar 4)
	5
	> x
	100
	> (set! x (bar x))
	101
	> x
	101
また関数のパラメータ以外でも,defineを用いて局所変数を定義することができる.
	> (define (f x)
	    (define y (* x x))
	    (+ 1 x y))
	> (f 2)
	7

局所関数

	> (define (f x y)
	    (define (g z)
	      (* 2 z))
	    (+ (g x) (g y)))
ここで,関数fの内部で定義されている関数gは局所関数であり,関数fの中でのみ有効となる.
	> (define (g i) ;; 大域関数g
	    (+ i 2))
	> (f 1 2) ;; この中では,局所関数gが有効
	6

このようにdefineを用いて,局所変数・局所関数を定義することはできるが,一般的にはlet,let*,letrecといった式を用いる. これは,let式などの方がより柔軟にスコープを制御できるためである.


[Prev]    [ Up ]    [Next]