计划中的匿名宏

Sho*_* Ya 1 lisp compiler-construction macros scheme functional-programming

我最近正在学习计划并且对一个没有标识符就无法评估宏的设计感到好奇,而lambda(程序)可以这样做.

例如,我可以使用匿名lambda:

((lambda x x) 1 2 3)
Run Code Online (Sandbox Code Playgroud)

似乎我必须使用以下语法定义宏:

(define-macro my-macro (lambda x x))
Run Code Online (Sandbox Code Playgroud)

我很好奇为什么这样的方法会像这样直接创建一个宏:

(define my-macro (macro-lambda x x))
Run Code Online (Sandbox Code Playgroud)

我想如果将宏和lambda视为不同的类型,第二个可能更优雅.

我的问题是:

  1. 怎么define-macro办?
  2. 宏和lambda之间的根本区别是什么?
  3. 方案中是否有匿名宏,如果没有,为什么?

soe*_*ard 5

首先是一个如何模拟"匿名宏"的例子.然后我会评论它的用处.

考虑这个匿名宏变换器,它接受表示数字的语法对象并返回表示输入数字的double的新语法对象.

(? (stx) 
  (datum->syntax stx
    (* 2 (syntax->datum stx))))
Run Code Online (Sandbox Code Playgroud)

我们可以这样测试:

> ((? (stx) 
    (datum->syntax stx
      (* 2 (syntax->datum stx))))
  #'3)
Run Code Online (Sandbox Code Playgroud)

结果是一个带有6的语法对象.

如果我们想要实际数字6,我们可以使用eval.

> (eval ((? (stx) 
          (datum->syntax stx
            (* 2 (syntax->datum stx))))
        #'3))
6
Run Code Online (Sandbox Code Playgroud)

现在我们使用匿名语法转换器将3重写为6.

匿名宏有用吗?

匿名函数用于您执行函数的位置,但您只需要一次.如果在程序中使用两次相同的匿名函数,最好给它一个名字,然后再引用它两次.

语法转换的情况也是如此.如果你需要至少两次相同的转换,你应该给它一个名字.匿名语法转换唯一有意义的是,如果仅使用一次.在大多数情况下,只编写转换结果会更简单.我想不出一个例子,匿名转换会让事情更简单.

注意:所有示例都在Racket中进行了测试.