俺letとaif

一回休んだけれど、30分プログラム、その52。

Schemeで俺letとaifを定義してみよう。
define-syntax系の健全なマクロでは無理だったので、define-macroの伝統的なマクロで実現した。
伝統的なマクロだと、Common Lispとまったく一緒やね。

俺letはとくに説明がいらないと思うので、aifの説明だけ。
aifはアナフォリックマクロといって、条件部の評価結果がitにバインドされる。
だから、

gosh> (aif (+ 1 3) it 0)
4

となる。

(define-syntax mac
  (syntax-rules()
    ((_ var) 
     (print (macroexpand-1 'var)))))
 
(define-macro (my-let binds . rest)
  (let ((vars (map (lambda(x) (if (pair? x) (car x) x)) binds))
	(vals (map (lambda(x) (if (pair? x) (cadr x) ())) binds)))
    `((lambda ,vars ,@rest)
      ,@vals)))
 
(define-macro (aif test then . opt)
  (let1 else (if (pair? opt) (car opt) ())
	`(let1 it ,test
	       (if it ,then ,else))))
 
(my-let ((x 1) (y 2) (z 3))
	(+ x y z))
  • いいかげんマクロの勉強に飽きてきた
  • 次は、モジュールをやろう
  • Schemeでもoptionalな引数がほしい