2010/05/09

Re:Re: 読んだ「The Seasoned Schemer」

紛らわしい気がしたので、define を def にしました。
あと、以下のようなマクロを書いてみました。
(define-syntax tss-lisp-eval
(syntax-rules ()
((_ expr)
(value (quote expr)))))
(define-syntax multi-tss-lisp-eval
(syntax-rules ()
((_ expr)
(tss-lisp-eval expr))
((_ expr1 expr2 ...)
(begin (tss-lisp-eval expr1)
(multi-tss-lisp-eval expr2 ...)))))
(define my-lisp multi-tss-lisp-eval)
view raw test-tss.scm hosted with ❤ by GitHub

で、この小さなLisp処理系には、数値演算がadd1とsub1しかありません。add1 と sub1 は、それぞれインクリメントとデクリメントです。

四則演算できるように、小さなLisp処理系自身を使って +, -, *, / などを追加。こちらも紛らわしいので、プレフィックスにアンパサンド(なんでも良かったんですが)を付けました。

def と &-, &* を用いて、階乗(fact)も定義できました。
(my-lisp
(def &+
(lambda (n m)
(cond ((zero? m) n)
(else (&+ (add1 n)(sub1 m))))))
(def &-
(lambda (n m)
(cond ((zero? m) n)
(else (&- (sub1 n)(sub1 m))))))
(def &*
(lambda (n m)
(cond ((zero? m) 0)
(else (&+ n (&* n (sub1 m)))))))
(def &>
(lambda (n m)
(cond ((zero? n) #f)
((zero? m) #t)
(else (&> (sub1 n)(sub1 m))))))
(def &<
(lambda (n m)
(cond ((zero? m) #f)
((zero? n) #t)
(else (&< (sub1 n)(sub1 m))))))
(def &=
(lambda (n m)
(cond ((&> n m) #f)
((&< n m) #f)
(else #t))))
(def &^
(lambda(n m)
(cond ((zero? m) 1)
(else (&* n (&^ n (sub1 m)))))))
(def &/
(lambda (n m)
(cond ((&< n m) 0)
(else (add1 (&/ (&- n m) m)))))))
(my-lisp (&* 5 6))
; -> 30
(my-lisp (&/ 25 5))
; -> 5
(my-lisp
(def fact
(lambda (n)
(cond
((zero? n) 1)
(else (&* n (fact (&- n 1)))))))
(fact 5))
; -> 120
view raw test-tss2.scm hosted with ❤ by GitHub

ちなみに、四則演算は The Little Schemer, 4th Edition の4章である「Numbers Games」を参考にしました。

追記

ソースはここ

The Little Schemer, 4th EditionThe Seasoned Schemer

0 件のコメント:

コメントを投稿