[英]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-rule
和apply
,但是由于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.