ifをlambdaで頑張ってみた

第1回SICP勉強会@名古屋大学 - YasuyukiMiuraの日記辺りでlambda使って評価タイミングをずらせば、ifの代わりになるんじゃないかという話が出てたのでやってみました。

(define-syntax my-if
  (syntax-rules ()
    ((my-if c t e) ; (my-if condition then else)
     (or (and c
              ((lambda () t)))
         ((lambda () e))))))

(define (hoge) (display "hoge\n"))
(define (fuga) (display "fuga\n"))

動かしてみる

% gosh -l ./my-if.scm
gosh> (my-if (= 3 3) (hoge) (fuga))
hoge
#<undef>
gosh> (my-if (= 3 0) (fuga) (hoge))
hoge
#<undef>
gosh> (my-if (= 3 3) (hoge) XXXXX)
hoge
#<undef>
gosh> (my-if (= 3 3) (max 3 4 5) (min 3 4 5))
5
gosh> (my-if (= 3 0) (max 3 4 5) (min 3 4 5))
3

(my-if (= 3 3) (hoge) XXXXX)
がちゃんと動くのが大切な所で、

     (or (and (= 3 3)
              ((lambda () (hoge))))
         ((lambda () XXXXX)))

と展開されるから、XXXXXを評価しなくてよいのでエラーにならずに済む。