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-11-07

KMRCLを眺める (8) alambda

| 02:11 | KMRCLを眺める (8) alambda - わだばLisperになる を含むブックマーク はてなブックマーク - KMRCLを眺める (8) alambda - わだばLisperになる

今日は、KMRCLのmacros.lispの中からALAMBDAです。

ArcにもALAMBDAがあるのですが、LAMBDAがfnになっていることもありALAMBDAではなくて、afnとして存在しています。

これまで見てきたマクロはは、ITを暗黙に値が束縛された変数名としていましたが、ALAMBDAの場合は、自分自身にSELFという名前を付けます。

使われ方としては、

(FUNCALL (ALAMBDA (N)
           (IF (< N 2)
               N
               (+ (FUNCALL #'SELF (1- N))
                  (FUNCALL #'SELF (- N 2)))))
         10))
;⇒ 55

という感じでしょうか。

いきなり脱線で、

#+SBCL
(DEFUN |TAO-(_| (STREAM IGNORE)
  (CASE (PEEK-CHAR T STREAM)
    ((#\_)
     (READ-CHAR STREAM)
     (LET ((EXPR (SB-IMPL::READ-LIST STREAM IGNORE)))
       (IF (CONSP (CAR EXPR))           ;適当すぎ
           `(FUNCALL ,(CAR EXPR)
                     ,@(CDR EXPR))
           `(FUNCALL (FUNCTION ,(CAR EXPR))
                     ,@(CDR EXPR)))))
    (OTHERWISE
     (SB-IMPL::READ-LIST STREAM IGNORE))))

(DEFREADTABLE :TAO_
  (:MERGE :STANDARD)
  (:MACRO-CHAR  #\( #'|TAO-(_|)
  (:CASE :UPCASE))

のようなリーダーマクロを定義して、

(IN-READTABLE :TAO_)

(_(ALAMBDA (N)
    (IF (< N 2)
        N
        (+ (_SELF (1- N))
           (_SELF (- N 2)))))
  10)
;⇒ 55

と最近の?TAO風(CiNii 論文 -  Lispへのオブジェクト指向の自然な導入)に書けるようにするとFUNCALLがすっきりして見やすくなるかもしれません。

マクロの定義は、こんな感じです。

(defmacro alambda (parms &body body)
  `(labels ((self ,parms ,@body))
     #'self))

LABELSを使ってローカル関数を定義して、ボディ部で外にSELFを放り投げていますが、ナイスなアイデアですね。

自分はCLではあまりALAMBDAを使いたくなったことはないのですが、Arcのafnは標準の備え付けということと、LISP-1の見た目のすっきり感もあり、割と好きで使います。

もっと関数型っぽいスタイルが好きな人はYコンビネータを使うのかもしれません。

ゲスト



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