我有一个Scheme宏和一个长列表,我想在列表中映射宏,就像它是一个函数一样。我怎么能用R5RS做到这一点?
宏接受几个参数:
(mac a b c d)
列表有
(define my-list ((a1 b1 c1 d1)
(a2 b2 c2 d2)
...
(an bn cn dn)))
我想要这个:
(begin
(mac a1 b1 c1 d2)
(mac a2 b2 c2 d2)
...
(mac an bn cn dn))
(顺便说一句,正如你所看到的那样,我也希望拼接参数列表)
答案 0 :(得分:2)
语法扩展被扩展为 评估开始时的核心形式 (在编译或解释之前) 通过语法扩展器。 -Dybvig,“The 方案编程语言:
宏操作语法。这在编译或执行之前发生。它为您提供了另一种编写相同代码的方法。
函数对变量和值(可能是列表,原子,数字等)进行操作,在调用函数时,它的值是已知的。
因此映射宏没有意义。你要求调用很久以前就已发生过的事情(宏扩展)。
如果您需要为您编写代码并在运行时对其进行评估,那么可能就是您需要eval
的情况之一。
答案 1 :(得分:1)
扩展z5h使用eval的答案,下面的方法显示了如果在使用的R5RS版本中实现了交互环境,如何编写map-macro宏:
(define test-list '((1 2 3 4)
(5 6 7 8)))
;Or if your version of scheme implments interaction-environment then:
(define-syntax trade
(syntax-rules ()
((_ a b c d) (display (list b a d c)))))
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
;Careful this is not really mapping. More like combined map and apply.
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
(define-syntax map-macro
(syntax-rules ()
((_ mac ls) (let ((mac-list (map (lambda (lst) (cons 'trade lst)) ls)))
(eval
`(begin
,@mac-list)
(interaction-environment))))
))
(map-macro trade test-list)
;outputs: (2 1 4 3)(6 5 8 7)
以便最后一次map-macro调用评估以下内容:
最终从(map-macro trade test-list)获得评估的是:
(begin
(trade 1 2 3 4)
(trade 5 6 7 8))
这不是一张地图,但我相信它确实回答了你的问题。
答案 2 :(得分:0)
会像
(map (lambda (l) (mac (car l) (caar l) (caaar l) (caaaar l))) mylist)
工作?