Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2009-12-05

KMRCLを眺める (31) defconstant*

| 19:56 | KMRCLを眺める (31) defconstant* - わだばLisperになる を含むブックマーク はてなブックマーク - KMRCLを眺める (31) defconstant* - わだばLisperになる

今回は、KMRCLのmacros.lispの中からDEFCONSTANT*です。

DEFCONSTANT*は割と定番のマクロな気がします。

定義は、

(defmacro defconstant* (sym value &optional doc)
  "Ensure VALUE is evaluated only once."
   `(defconstant ,sym (if (boundp ',sym)
                          (symbol-value ',sym)
                          ,value)
     ,@(when doc (list doc))))

という感じで、変数を再度DEFCONSTANTしてしまうのを防ぐマクロです。

DEFCONSTANTは、コンパイル時やロード時に評価されるかどうかは処理系が好きにして良いらしく、SBCL等ではコンパイル時にも評価されます。

;; /tmp/foo.lispというファイル
(DEFCONSTANT +CONST+ 42)
;; SBCL
(COMPILE-FILE "/tmp/foo.lisp")
+CONST+
;⇒ 42
;; Allegro CL
(COMPILE-FILE "/tmp/foo.lisp")
+CONST+
;>>> Attempt to take the value of the unbound variable `+CONST+'.

というわけなので、SBCLだとファイルをロードしなくてもDEFCONSTANTの再定義でぶつかることがあります。

The constant +CONST+ is being redefined (from 42 to 43)
   [Condition of type DEFCONSTANT-UNEQL]
See also:
  Common Lisp Hyperspec, DEFCONSTANT [:macro]
  SBCL Manual, Idiosyncrasies [:node]

というようなエラーはSBCLだとライブラリを読み込むときに良く遭遇しますが、こういうケースをDEFCONSTANT*だと回避できるわけですね。