変数の話

かなりの確率で間違っている変数のメモ

■defvarで変数を作るときに**で挟む理由
 の勝手な理解、defvarはスペシャル変数で、どこからでも参照できる変数のようなので*で挟むことで他の変数と名前の重複を避ける。もし他でdefvarと同じ変数名を使ってしまうと、そのときに書き換えてしまいそうなので、其れ避けのような風に思った。

■defvar-localな変数は *-* な名前にしない。
defvar-localはスペシャル変数ではないので*ではさむ必要はない。というか挟まない方が良いらしい。
参考:http://ohkubo.s53.xrea.com/diary/0910.html

■勝手な脳内イメージ
軸は二つじゃないかと。勝手に妄想。
  バッファグローバル <=> バッファローカル*1
  スペシャル変数 <=> レキシカル変数

言葉的には
スペシャル=グローバル=動的バインディング=ダイナミック
レキシカル=ローカル =静的バインディング

■もう一つの関係性

  • 参照のしやすさ。*2
  • 優先される度合い。同じ名前の変数がある場合の優先順位

■昨日自分が書いた優先度の勘違い
 勘違い : 優先度合いはletよりdefvar-localの方が高い。
実際は

  (defvar var 3)
  (defvar-local var-local 3)
  (defun foo () (let ((var 4) (var-local 4)) (bar)))
  (defun bar () (format nil "var : ~S, var-local : ~S" var var-local))

  (defun hoge () (let ((var 4) (var-local 4))
				  (format nil "var : ~S, var-local : ~S" var var-local)))

こういうのを書いて実行すると

(foo)
=>
"var : 4, var-local : 3"

(hoge)
=>
"var : 4, var-local : 4"

var
=>
3
var-local
=>
3

 こういうことらしい。つまり、関数となっている場合はletの括弧からでちゃってるよとかいう扱いと言う意味の様子。referenceのdefvar-localの所の例とか疲れた状態でみていたらなんかbarが関数だということを忘れて色々勘違いしてきていたということの様子。*3

■もっとまともな解説を見たい人向け。
詳しくは
M.Hiroi's Home Page / xyzzy Lisp Programming
http://www.geocities.jp/m_hiroi/xyzzy_lisp/abclisp10.html
ここに事細かに書いてあった。

silog - diary/2006-10-11/スコープについて
http://white.s151.xrea.com/wiki/index.php?diary%2F2006-10-11%2F%A5%B9%A5%B3%A1%BC%A5%D7%A4%CB%A4%C4%A4%A4%A4%C6
こっちにも

*1:GNU Emacs Lispリファレンスマニュアル: 10. 変数 http://www.fan.gr.jp/~ring/doc/elisp_20/elisp_11.html#SEC149

*2:そもそも変数を参照できる位置が決まっているので。例えばletならば基本はletの括弧内でのみ参照する

*3:まあ、ファイアプロジェクトの無茶な引数とかの所を見てて感覚が麻痺していたというもあるけど。