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

Macros 如何在Scheme中的列表中映射宏?,macros,scheme,Macros,Scheme,我有一个Scheme宏和一个长列表,我希望将宏映射到整个列表,就像它是一个函数一样。如何使用R5R实现这一点 宏接受多个参数: (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

我有一个Scheme宏和一个长列表,我希望将宏映射到整个列表,就像它是一个函数一样。如何使用R5R实现这一点

宏接受多个参数:

(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))
(顺便说一句,正如你所看到的,我还想拼接参数列表)

你想

(map (lambda (l) (mac (car l) (caar l) (caaar l) (caaaar l))) mylist)
工作

语法扩展扩展扩展为 评估开始时的核心表格 (汇编或解释前) 通过语法扩展器-迪布维格,“这个 方案编程语言:

宏根据语法进行操作。这发生在编译或执行之前。它提供了编写相同代码的另一种方法

函数对变量和值(可能是列表、原子、数字等)进行操作,调用该函数时已知哪些变量和值

所以映射一个宏是没有意义的。你要求调用一些很久以前已经发生过的事情(宏扩展)


如果您需要为自己编写代码并在运行时对其进行评估,那么可能是需要
eval

扩展z5h使用eval的答案的情况之一,下面的方法显示了如果在使用中的R5RS版本中实现了交互环境,则如何编写映射宏宏:

(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宏调用将计算以下内容:

最终从(map宏交易测试列表)中得到评估的是:


这不是一个完整的映射,但我相信它确实回答了您的问题。

宏接受varargs,因此上面的解决方案会导致错误。我不明白为什么这意味着您会出错。您的意思是,我的列表中的列表可能有不同的长度吗?@Jay Korninek宏可能会操纵a1 b1中的内容……因为我没有这样做我们可以假设它们是原子的如果宏没有包含那么多参数,可能会发出错误信号。我想要一些真正通用的东西…我认为让你的问题更具体可能会有帮助。a1 b1是什么?它们是原子的吗?它们是代码吗?在不了解更多数据的情况下,宏z5H可能有最好的答案。不限制a1 b1…是什么。可能在oms,可以是列表,随便什么……我相信他希望在编译之前扩展宏(对吗?)。我不确定Scheme,但我在使用defmacro的公共Lisp中做了很多(defmacro中的代码将使用许多其他函数来转换S表达式(甚至使用全局哈希表!)。一个宏将定义多个函数…因此这基本上意味着我不能选择编写一个“映射语法”宏,该宏将迭代地(在宏本身中)展开,直到为列表的所有成员展开mac?(当然,我必须将列表传递给宏,而不是在变量中!)如果在首选版本的R5RS方案中有交互环境,则可以有效地编写映射宏。交互环境在R5RS规范中是可选的。它确实存在于DrScheme或其他新名称中。我编辑了我的答案,以给出映射宏的示例。
(begin
  (trade 1 2 3 4)
  (trade 5 6 7 8))