创建一个使用宏返回核心表达式的函数

时间:2014-10-28 20:52:48

标签: macros lambda scheme

我一直在使用R5RS编写一些代码,以便使用宏将某些表达式扩展为表达式的核心形式。这些是稍后提供的eval / apply循环

(define expand (lambda (exp)

(letrec-syntax 
    ((let (syntax-rules ()
        ((_ ((var init) ...) body ...) 
        (`((lambda (var ...) body ...) init ...))))) )
    (exp)) ; sequence to expand
))
(expand (let ((x 2) (y 1)) (+ x y)) )

当我运行这样的代码时,我回到;The object 3 is not applicable.,但看起来它实际上正在评估exp,但我需要回到一个呃...字符串表示。

如果我将我希望扩展的表达式嵌入到letrec语法体中,我会得到我真正想要的内容。像这样:

(define expand (lambda (exp)

(letrec-syntax 
    ((let (syntax-rules ()
        ((_ ((var init) ...) body ...) 
        (`((lambda (var ...) body ...) init ...))))) )
    (let ((x 2) (y 1)) (+ x y))) ; sequence to expand
))

我回来了...... ;The object ((lambda (x y) (+ x y)) 2 1) is not applicable看起来像我要发回的内容被解释。

所以我的问题是我怎样才能重写这个,以便像第一个例子那样扩展任何exp,但是像第二个例子那样返回它的扩展形式?

我认为这个问题与lambda在letrec-syntax方面的错误范围内定义的exp有关。我对Scheme很新,我觉得我在这里错过了一个简单的解决方案。到目前为止,我最好的导致涉及使用语法案例或某种方式关于卫生,但我觉得我一直在追逐我的尾巴试图研究这些主题到目前为止,我不确定他们是正确的方向。

感谢您的帮助。 :)

1 个答案:

答案 0 :(得分:0)

这有效:

(define-syntax expand 
  (syntax-rules (let)
    ((_ (let ((var init) ...) body ...))
     '((lambda (var ...) body ...) init ...))))

然后

> (expand (let ((x 2) (y 1)) (+ x y)))
((lambda (x y) (+ x y)) 2 1)