let

マクロの練習に、自分でletを定義してみた。

(define-syntax my-let
  (syntax-rules ()
    ((my-let ((var init) ...) expr ...)
     ((lambda (var ...) (begin expr ...)) init ...))
    ((my-let fname ((var init) ...) expr ...)
     (my-let ((fname #f))
             (set! fname (lambda (var ...) (begin expr ...)))
             (fname init ...)))))

fnameを再帰させるところが本と少し違うようだ。
で、次に階乗計算のfact。名前付きmy-letを使うために、わざとらしく継続渡しで(?)書いてみた。

gosh> (define fact
        (lambda (n)
          (my-let loop ((n n)
                        (cont (lambda (m) m)))
            (if (= n 0)
                (cont 1)
                (loop (- n 1) (lambda (m) (cont (* n m))))))))
fact
gosh> (map fact '(1 2 3 4 5 6))
(1 2 6 24 120 720)