如何在Scheme中的列表中映射宏?

时间:2010-04-14 18:35:39

标签: macros scheme

我有一个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))

(顺便说一句,正如你所看到的那样,我也希望拼接参数列表)

3 个答案:

答案 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)

工作?