1

我将如何做一个define-syntax-rule接受一个列表作为参数和一个列表(或引用,如果它是一个元素)作为 lambda 的主体?我想做类似的事情:

    >(define a (lambdarize '(x y z) '(+ x y z)))
    #<procedure>
    >(a 1 2 3)
    6
    >(define b (lambdarize '(x) 'x))
    #<procedure>
    >(b 1)
    1

我玩过define-syntax-ruleand apply,但由于lambda它本身似乎是一个宏而不是一个过程,我一直很难找到它......

哦...我想要一个不使用的解决方案eval,因为它是有害的...

更新

谢谢你的回答,瑞恩......几乎做到了!=) eval 的问题在于它不擅长捕捉当前范围......这样我可以做类似的事情

    (let ([a 1])
        (begin
            (defmethod add ((x integer?) (y integer?)) (+ x y a))
            (add 1 2)
    )

eval 会惨遭失败……这只是一个学术例子,但我认为这是对正确性的一个很好的测试。

4

1 回答 1

2

在不使用eval.

但根据您对 Greg 评论的回答,您可以更改defmethod宏以避免此问题。您当前的方法采用变量和主体表达式(程序术语),将它们转换为运行时值,然后希望将它们重新解释为程序术语。相反,您应该将程序术语组合到lambda宏中的 - 表达式中,然后您可以将其作为值传递给辅助函数:

(define-syntax-rule (defmethod name ((var predicate) ...) body)
  (add-to-generic name
                  (list predicate ...)
                  (lambda (var ...) body)))

如果您想保留变量名称(例如用于错误消息),您也可以引用它们,但与 - 表达式分开lambda

(define-syntax-rule (defmethod name ((var predicate) ...) body)
  (add-to-generic name
                  (list predicate ...)
                  '(var ...)                 ;; for errors, debugging, etc
                  (lambda (var ...) body)))
于 2013-05-08T16:18:35.090 回答