2010/08/20

レキシカルスコープとダイナミックスコープ

  • scheme
    • レキシカルスコープ
  • Common Lisp
    • レキシカルスコープ
    • ダイナミックスコープ
  • Emacs Lisp
    • ダイナミックスコープ
という認識で良いかと思います。Clojure や Arc なんかもたぶんレキシカルスコープでしょう(たぶん)。
Common Lisp はスペシャル変数(だけ?)がダイナミックスコープですよね。

scheme にはダイナミックスコープな変数をエミュレートする fluid-let という変数束縛マクロがあったりします。
で、なんと Emacs Lisp には lexical-let マクロという、レキシカルスコープな変数をエミュレートするマクロがあるらしいじゃないですか。(cl パッケージだけど)
ソース見てみたんですが、正直よくわかりませんでした。。

Emacs Lisp と lexical-let の場合。
(require 'cl)

(defvar a 100)
a
;; 100

(defvar b 200)
b
;; 200

(defun a+b ()
  (+ a b))

(a+b)
;; 300

(let ((a 1)(b 2))
  (values (a+b)(+ a b)))
;; (3 3)

(lexical-let ((a 1)(b 2))
  (values (a+b)(+ a b)))
;; (300 3)

ついでに、scheme と fluid-let の場合。
(use srfi-15)

(define a 100)
a
;; 100

(define b 200)
b
;; 200

(define (a+b)
  (+ a b))

(a+b)
;; 300

(let ((a 1)(b 2))
  (values (a+b) a b))
;; 300
;; 1
;; 2

(fluid-let ((a 1)(b 2))
  (values (a+b) a b))
;; 3
;; 1
;; 2

Scheme 以前の太古の Lisp は皆ダイナミックスコープだったらしいですね。こわい。
Common Lisp のスペシャル変数は便利だなぁ、と思っていました。でも Emacs Lisp のように原則ダイナミックスコープっていうのはどうなんだろう。すごく難しそうな気がするんですが、どうなんでしょう。。

0 件のコメント:

コメントを投稿