Macros 如何将输入模式中的文字标识符作为符号插入语法规则宏中

Macros 如何将输入模式中的文字标识符作为符号插入语法规则宏中,macros,scheme,hygiene,Macros,Scheme,Hygiene,我有这样的代码: (定义语法宏) (语法规则() ((姓名) (λ(x) (eval(cons的名字x)(交互环境(()())))) (定义x(映射(马克龙λ) "((x)((x))((ab)("ab")(" (让((方形(车x)) (总和(cadr x))) (显示器(方格10)) (新行) (显示(总和1 2 3)) (新行) 代码使用lambda包装宏作为值。我的问题是如何将语法规则宏文字符号'name替换为(cons'lambda…),因此输出代码是: (λ(x) (评估(cons名称

我有这样的代码:

(定义语法宏)
(语法规则()
((姓名)
(λ(x)
(eval(cons的名字x)(交互环境(()()))))
(定义x(映射(马克龙λ)
"((x)((x))((ab)("ab")("
(让((方形(车x))
(总和(cadr x)))
(显示器(方格10))
(新行)
(显示(总和1 2 3))
(新行)
代码使用lambda包装宏作为值。我的问题是如何将语法规则宏文字符号
'name
替换为
(cons'lambda…
),因此输出代码是:

(λ(x)
(评估(cons名称x)(交互环境)))
因此,它可以处理如下代码:

(定义(名称x)
(显示器x)
(新行)
(对于每个(马克龙λ);;λ可以是任何东西
'((1) (2) (3)))
它会打印所有的数字

我知道我可以将模式中的名称更改为其他名称,但我想更多地了解语法规则及其边缘情况。所以,如果我将其用作输入模式,是否可能有名称


我正在寻找R7RS的答案,它涵盖了更多此类边缘情况。

所有宏都发生在编译时,因此运行时的东西可能不存在。这意味着您应该将其视为语法糖,并将其用作susch。例如

(for-each (macron something) '((1) (2) (3)))
然后应该在此基础上进行扩展。您当前的扩展是将其转化为:

(for-each (lambda (x)
            (eval (cons 'someting x) (interaction-environment))
          '((1) (2) (3)))
对于
某物
作为宏,这将在运行时应用宏。这很糟糕。它还从一开始就消除了对宏的需要。您可以这样做:

(define (macron-proc name)
  (lambda (x)
    (eval (cons name x) (interaction-environment))))

(for-each (macron-proc 'something) '((1) (2) (3)))
我制作了一种具有可通过宏的编程语言:

(define xor (flambda (a b) `(if ,a (not ,b) ,b)))
(define (fold comb init lst)
  (if (null? lst)
      init
      (fold comb (comb (car lst) init) (cdr lst))))
(fold xor #f '(#t #t)) ; ==> #f
如果您的目标是高效编译的最终产品,那么这不是一个很好的方法。第一个宏确实是这样的,在Common LISP之前,他们在LISP 1.5中删除了它。Scheme多年来一直避免使用宏,并选择R4RS中的
语法规则作为可选功能。R6RS是唯一具有全功率宏的版本

使用过程而不是宏,这实际上与以下代码相同,并删除了错误的
eval

(for-each (lambda (x)
            (apply something x))
          '((1) (2) (3)))
这意味着您可以更轻松地实现
macron

(define-syntax macron
  (syntax-rules ()
    ((_ name)
     (lambda (x)
       (apply name x)))))
但是从现在开始,你根本不需要宏。这是部分应用

(define (partial proc arg)
  (lambda (lst)
    (apply proc arh lst)))

(map (partial + 3) '((1 2) (3 4) (4 5)))
; ==> (6 10 12)
实际上有一个叫做
cut
/
cute
的程序,它允许我们在lambda中进行类似的操作:

(map (cut apply + 3 <>) '((1 2) (3 4) (4 5)))
(地图(切割应用+3)”((1 2)(3 4)(4 5)))
语法规则
是功率最小的宏。你不能做任何不卫生的事情,也不能基于其他标识符来制作新的标识符。例如,不可能实现一个球拍样式的结构,在这里你可以做
(结构复杂[real imag])
,并让宏创建
复杂?
复杂真实
,和
复杂imag
作为过程。您需要这样做,并要求euser指定所有名称,这样您就不需要连接到新的标识符


目前R7RSSmall只有
语法规则
。我认为没有一个更强大的宏作为替代是错误的,因为现在R7RS大的不能用R7RS小的实现。

所有宏都发生在编译时,所以运行时的东西可能不存在。这意味着您应该将其视为语法糖,并将其用作susch。例如

(for-each (macron something) '((1) (2) (3)))
然后应该在此基础上进行扩展。您当前的扩展是将其转化为:

(for-each (lambda (x)
            (eval (cons 'someting x) (interaction-environment))
          '((1) (2) (3)))
对于
某物
作为宏,这将在运行时应用宏。这很糟糕。它还从一开始就消除了对宏的需要。您可以这样做:

(define (macron-proc name)
  (lambda (x)
    (eval (cons name x) (interaction-environment))))

(for-each (macron-proc 'something) '((1) (2) (3)))
我制作了一种具有可通过宏的编程语言:

(define xor (flambda (a b) `(if ,a (not ,b) ,b)))
(define (fold comb init lst)
  (if (null? lst)
      init
      (fold comb (comb (car lst) init) (cdr lst))))
(fold xor #f '(#t #t)) ; ==> #f
如果您的目标是高效编译的最终产品,那么这不是一个很好的方法。第一个宏确实是这样的,在Common LISP之前,他们在LISP 1.5中删除了它。Scheme多年来一直避免使用宏,并选择R4RS中的
语法规则作为可选功能。R6RS是唯一具有全功率宏的版本

使用过程而不是宏,这实际上与以下代码相同,并删除了错误的
eval

(for-each (lambda (x)
            (apply something x))
          '((1) (2) (3)))
这意味着您可以更轻松地实现
macron

(define-syntax macron
  (syntax-rules ()
    ((_ name)
     (lambda (x)
       (apply name x)))))
但是从现在开始,你根本不需要宏。这是部分应用

(define (partial proc arg)
  (lambda (lst)
    (apply proc arh lst)))

(map (partial + 3) '((1 2) (3 4) (4 5)))
; ==> (6 10 12)
实际上有一个叫做
cut
/
cute
的程序,它允许我们在lambda中进行类似的操作:

(map (cut apply + 3 <>) '((1 2) (3 4) (4 5)))
(地图(切割应用+3)”((1 2)(3 4)(4 5)))
语法规则
是功率最小的宏。你不能做任何不卫生的事情,也不能基于其他标识符来制作新的标识符。例如,不可能实现一个球拍样式的结构,在这里你可以做
(结构复杂[real imag])
,并让宏创建
复杂?
复杂真实
,和
复杂imag
作为过程。您需要这样做,并要求euser指定所有名称,这样您就不需要连接到新的标识符


目前R7RSSmall只有
语法规则
。我认为没有一个更强大的宏作为替代是一个错误,因为现在R7RS大的不能用R7RS小的实现。

你能不能只做一个模式
(\uu)
?然而,仅仅存在
eval
这一点就足够可怕了,我不确定。@tfb你知道有没有其他方法可以用语法规则和不使用eval来创建类似宏的宏?我想在宏上应用,但找不到任何其他方法。我无法确定您实际想做什么。如果你描述了这一点,那么我敢肯定有比这更好的答案。你不能只做一个模式
(uuu)
?然而,仅仅是
e的存在