2010/04/06

defmacro: LOL nlet

マクロは、Lispが1つのプログラミング言語として有する唯一最大の強みであり、いかなるプログラミング言語においても唯一最大の強みである。  --Doug Hoyte
著者のLisp(のマクロ)マンセーっぷりがすごい。
(Gaucheで書いてみてます)
;; nlet
(define-macro (nlet n letargs . body)
`(letrec ((,n (lambda ,(map car letargs)
,@body)))
(,n ,@(map cadr letargs))))
(define (fact n)
(nlet loop ((n n))
(if (zero? n)
1
(* n (loop (- n 1))))))
(fact 5)
; -> 120
(let loop ()
(display 1))
; -> 1#<undef>
(define-syntax nlet
(syntax-rules ()
((_ name ((var val) ...) body ...)
(letrec ((name (lambda (var ...)
body ...)))
(name val ...)))))
(define (fact n)
(nlet loop ((n n))
(if (zero? n)
1
(* n (loop (- n 1))))))
(fact 5)
; -> 120
view raw nlet.scm hosted with ❤ by GitHub


プログラミングGaucheLET OVER LAMBDA Edition 1.0

4 件のコメント:

  1. Gauche 限定でならマクロを使わずに nlet を定義できちゃったり。
    (define nlet let)

    返信削除
  2. named-letってことですよね。
    LOLを読みながらGaucheで写経したりしようかなーと(笑)

    返信削除
  3. すいません。 言葉が足りませんでした。 練習のための写経なのはわかっているので scheme の named-let のことを言いたかったのではないです。
    特殊構文やマクロはファーストクラスのオブジェクトでは無いので普通の Scheme では define で別名を付けることは出来ないのですが、 Gauche では出来てしまうというちょっと変なところを紹介してみた次第です。 (実際、他に (define nlet let) が出来る Scheme 処理系を見付けることは出来ませんでした。)

    返信削除
  4. なるほどー!そういうことだったんですか!すいませんでした^^;

    >特殊構文やマクロはファーストクラスのオブジェクトでは無いので普通の Scheme では define で別名を付けることは出来ないのですが、 Gauche では出来てしまうというちょっと変なところを紹介してみた次第です。 (実際、他に (define nlet let) が出来る Scheme 処理系を見付けることは出来ませんでした。)

    そうだったんですか。評価すればなんでも値が返ってきていたので、それが普通なのかと思っていました。。

    なるほど、それがわかると(define nlet let)がすごくおもしろいですね(笑)勉強になります。ありがとうございました。

    返信削除