Emacs Lisp Intro で let のページを読んだ。
Another way to think about `let' is that it is like a `setq' that is temporary and local. The values set by `let' are automatically undone when the `let' is finished. The setting only affects expressions that are inside the bounds of the `let' expression. In computer science jargon, we would say "the binding of a symbol is visible only in functions called in the `let' form; in Emacs Lisp, scoping is dynamic, not lexical."
とあって、これがよく話題にあがるダイナミックスコープの説明(の断片)かーと思ったので試してみた。
Emacs Lisp
(defun foo () (message "value of `foo' is %s" foo)) ;=> foo (let ((foo "FOO")) (foo)) ;=> "value of `foo' is FOO"
Perl にただ翻訳すると、こうか?
#!/usr/bin/env perl use strict; use warnings; sub foo { printf "value of `foo' is %s", $foo; } { my $foo = "FOO"; foo(); } # $ perl foo.pl # Global symbol "$foo" requires explicit package name at foo.pl line 6. # Execution of foo.pl aborted due to compilation errors.
レキシカルスコープだと、自分自身のスコープか、自分自身を含んだ外側のスコープで未定義の変数は参照できなかったりするし、エラーにならなくても別のスコープの中で束縛された値にはアクセスできない。一方、ダイナミックスコープだと、関数が評価されるときにどのスコープから呼ばれたかを外側へ向かって逆にたどっていくので、関数定義の中でいきなり未定義の変数を参照してもエラーにならず値にアクセスできることがある。こういう理解で合ってるのかな?