はじめまして。
メモ帳の代わりとして使い始めたEmacsがそろそろ馴染んできたので、プログラミング初心者の視点で見つけた小ネタをたまに投稿していきます。
環境はWindows+gnupack Emacs 24.2です。それ以外はしらない。
-
今回のネタはタイトルのとおりです。defvarとdefconstの何が違うのか。再評価時に初期値が代入されるかどうかの違いとかはあるけど、だいたいdefvarもdefconstも好きに使えば?って感じだったので、何か明確な違いはないのかなって思ったらありました。
(defvar test-abc "abc")
(defun test-defvar (test-abc)
(message "%s" test-abc))
(defconst test-xyz "xyz")
(defun test-defconst (test-xyz)
(message "%s" test-xyz))
この子たちを、
(byte-compile-file "test-defvar.el")
-> t
(byte-compile-file "test-defconst.el")
-> nil Compile Error: Invalid lambda variable test-xyz
うわあ。コンパイル出来ない。
関数の[引数]にdefconstで定義した変数と同名のシンボルを置くとこうなります。
defconstはあくまで定数を宣言するフォームということですね。当然関数の引数に定数な名前を置くのはコードとして間違ってます。
でもelispだと定数相手にsetとかもいくらでも出来るので、定数宣言っていうのも注意書き程度のものだと思ってたけれど違った。
まさかコンパイラがエラー吐くとは思わなかった。出してもワーニングくらいだと思ってた。
それぞれ定義した関数はどっちも普通に動いてくれるので、関数はちゃんと動くのに何故かコンパイル出来ないってパターンにはまりそう。
ちなみにletで同名の局所変数をつくってもコンパイラさんに文句言われません。それもう定数じゃないじゃん。なっとくいかない。