【问题标题】:Creating a function to return a core expression using macros使用宏创建函数以返回核心表达式
【发布时间】:2014-10-28 20:52:47
【问题描述】:

我一直在编写一些代码,使用 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,但我需要返回一个 uh...string 表示形式。

如果我将想要扩展的表达式嵌入到 letrec-syntax 主体中,我会得到我真正想要的。像这样:

(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 定义的 exp 在 letrec 语法方面处于错误范围有关。我对 Scheme 很陌生,我觉得我在这里缺少一个简单的解决方案。到目前为止,我最好的线索涉及以某种方式使用语法案例或有关卫生的东西,但我觉得到目前为止我一直在追逐我的尾巴,试图研究这些主题,我不确定它们是否是正确的方向。

感谢您的帮助。 :)

【问题讨论】:

  • 你使用的是哪个 Scheme 实现?
  • MIT/GNU Scheme 基于来自here的R5RS

标签: macros lambda scheme


【解决方案1】:

这行得通:

(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)

【讨论】:

  • @uselpha MIT/GNU 方案似乎不喜欢 syntax-object->datum #' 部分,如果我删除它确实会在我调用 expand 之后返回表达式,但我得到了稍后在 (define interpret (lambda (exp) (exec (expand exp) '()) )) 中调用 expand 时出现格式错误的特殊格式错误
  • 好的,刚刚安装了 MIT-Scheme。请查看我的更新。
  • 你能解释一下 syntax-rules 中的 value (let) value 的作用吗?我在网上看到的所有地方都使用(syntax-rules () ((_)...)
  • 这被称为字面量,意思是在这个精确的位置,你必须把单词let 放在一边,别无其他。如果您省略在括号之间指定文字,您可以使用任何单词,它将绑定到一个名为 let 的变量,这不是您想要的。
  • 好吧,这是有道理的。我使用 letrec-syntax 的原因是因为我需要扩展其他关键字,例如 or 和 case 到核心表达式中,其中一些是我根据 let 递归定义的。您能否提供任何指导以向同一个表达式添加额外的语法规则,还是我需要单独定义每个?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-16
  • 1970-01-01
相关资源
最近更新 更多