繁体   English   中英

如何在球拍中创建一个宏,使列表成为所述lambda的参数?

[英]how to create a macro in racket where a list becomes the args of said lambda?

我该如何做一个将列表作为参数并且将列表(或者引号,如果是单个元素的话)作为lambda主体的define-syntax-rule 我想做类似的事情:

    >(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-ruleapply ,但是由于lambda本身似乎是一个宏而不是一个过程,所以我一直难以找到它。

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

UPDATE

感谢您的回答,瑞安...差不多做到了! =)eval的问题在于,它不擅长捕获当前范围...这样我可以做类似的事情

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

评估失败了……这只是一个学术例子,但我认为这是正确性的良好测试。

如果不使用eval ,则无法创建将形式参数和主体作为运行时值(S-expressions)给出的eval

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

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

如果要保留变量名(例如,对于错误消息),也可以用引号将它们括起来,但要与lambda -expression分开:

(define-syntax-rule (defmethod name ((var predicate) ...) body)
  (add-to-generic name
                  (list predicate ...)
                  '(var ...)                 ;; for errors, debugging, etc
                  (lambda (var ...) body)))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM