我很困惑,试图在MIT Scheme中创建相当于这个简单的(在Common Lisp中)宏:
(defmacro funcify (exp) `(lambda (x),exp))
这是一个简单的个人项目,一个基于第二次SICP讲座中建立的功能的数值方程求解器.我不在乎这个宏不是“安全”或“卫生”,或者如果exp引用除’x之外的任何符号,它将捕获变量.我想能写
(solv '(* 60 x) '(* 90 (- x 1)))
solv是:
(define (solv lh-exp rh-exp) (solve (funcify lh-exp) (funcify rh-exp)))
而不是必须打字
(solve (lambda (x) (* 60 x)) (lambda (x) (* 90 (- x 1))))
但无法弄清楚如何使用MIT Scheme语法规则来做到这一点.
我试过这个,但它不起作用:
(define-Syntax funcify (Syntax-rules () ((funcify y) (lambda (x) y)))) ;Value: funcify (funcify x) ;Value 17: #[compound-procedure 17] ((funcify x) 10) ;Unbound variable: x
我尝试过其他可能不值得一提的事情,但是无济于事.
另外,在Scheme的宏系统上引用了很好的教程(不是引用),从小的简单示例开始并构建,有充分的注释,特别是展示了如何将backquote-comma样式的LISP宏(对我而言非常直观)转换为Scheme的语法宏系统会很棒.
解决方法
你可以使用
explicit-renaming macros基本上和defmacro一样.唯一重要的区别是你必须自己解构输入表单:
(define-Syntax funcify (er-macro-transformer (lambda (form rename cmp) (let ((exp (cadr form))) `(,(rename 'lambda) (x),exp)))))