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

Filtered Functions面白そう

| 20:00 | Filtered Functions面白そう - わだばLisperになる を含むブックマーク はてなブックマーク - Filtered Functions面白そう - わだばLisperになる

今日公開されたFiltered Functionsが面白そうだったので、とりあえず、記念にfizzbuzzしてみました。

詳しくは、

を参照したり、リンク中の論文のPDFを参照してみてください。

;; ディスパッチの関数を利用する版
(DEFINE-FILTERED-FUNCTION FIZZBUZZ (N)
  (:FILTERS (:FIZZBUZZ
             (LAMBDA (N)
               (COND ((AND (ZEROP (REM N 3))
                           (ZEROP (REM N 5)))
                      'FIZZBUZZ)
                     ((ZEROP (REM N 3))
                      'FIZZ)
                     ((ZEROP (REM N 5))
                      'BUZZ)
                     ('T 'OTHER))))))

(DEFMETHOD FIZZBUZZ :FILTER :FIZZBUZZ ((N (EQL 'FIZZ)))
  'FIZZ)

(DEFMETHOD FIZZBUZZ :FILTER :FIZZBUZZ ((N (EQL 'BUZZ)))
  'BUZZ)

(DEFMETHOD FIZZBUZZ :FILTER :FIZZBUZZ ((N (EQL 'FIZZBUZZ)))
  'FIZZBUZZ)

(DEFMETHOD FIZZBUZZ :FILTER :FIZZBUZZ ((N (EQL 'OTHER)))
  N)
(KMRCL:FOR (I 1 100)
  (PRINT (FIZZBUZZ I)))
|1 
|2 
|FIZZ 
|4 
|BUZZ 
|FIZZ 
|7 
|8 
|FIZZ 
|BUZZ 
|11 
|FIZZ 
|13 
|14 
|FIZZBUZZ 
|...
;⇒ NIL
;; メソッドコンビネーション風味
(DEFINE-FILTERED-FUNCTION FIZZBUZZ2 (N)
  (:FILTERS (:3 (ZEROP (REM N 3)))
            (:5 (ZEROP (REM N 5)))
            (:3&5 (AND (ZEROP (REM N 5))
                       (ZEROP (REM N 3))))))

(DEFMETHOD FIZZBUZZ2 ((N NUMBER))
  N)

(DEFMETHOD FIZZBUZZ2 :AROUND :FILTER :3&5 (N)
  (DECLARE (IGNORE N))
  'FIZZBUZZ)

(DEFMETHOD FIZZBUZZ2 :AROUND :FILTER :3 (N)
  (DECLARE (IGNORE N))
  'FIZZ)

(DEFMETHOD FIZZBUZZ2 :AROUND :FILTER :5 (N)
  (DECLARE (IGNORE N))
   'BUZZ))
(KMRCL:FOR (I 1 100)
  (PRINT (FIZZBUZZ2 I)))
|1 
|2 
|FIZZ 
|4 
|BUZZ 
|FIZZ 
|7 
|8 
|FIZZ 
|BUZZ 
|11 
|FIZZ 
|13 
|14 
|FIZZBUZZ 
|...
;⇒ NIL

CLOS登場の初期には、Filtered Functionsのようにディスパッチの方法/拡張が色々研究されていたようなのですが、これをきっかけにまた色々活発になると面白そうですねー。

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*だと回避できるわけですね。

ゲスト



トラックバック - http://cadr.g.hatena.ne.jp/g000001/20091205