繁体   English   中英

为什么此语法可以模式化此“ for”宏?

[英]why this syntax can pattern this “for” macro?

#lang racket
(define-syntax for
  (syntax-rules ()
    ((_ list 'as element body ...)
     (map (lambda (element)
            body ...)
          list))))

>(对于'(0 1 2 3 4)'in i(print i)(换行符))

=> 0 1 2 3 4'(#####)

我的问题是,为什么“中的符号可以将符号”表示为? “ in”符号不是“ in”的唯一模式吗?

在球拍文档中, 有时会说

模板用来代替与模式匹配的形式,只是模板中每个模式变量实例被替换为使用匹配的模式变量的宏部分。

这让我认为'as符号被忽略了。 确实,这

(define-syntax for
  (syntax-rules ()
    ((_ list element body ...)
     (map (lambda (element)
            body ...)
          list))))
(for '(0 1 2 3 4) i (print i) (newline))

效果也一样。

要获得所需的行为,请使用

(define-syntax for
  (syntax-rules (as)
    ((_ list as element body ...)
     (map (lambda (element)
            body ...)
          list))))

然后

>  (for '(0 1 2 3 4) as i (print i) (newline))
0
1
2
3
4
'(#<void> #<void> #<void> #<void> #<void>)

>  (for '(0 1 2 3 4) in i (print i) (newline))    
for: bad syntax in: (for (quote (0 1 2 3 4)) in i (print i) (newline))

不评估宏模式。 特别地, 'as 不是符号。 它只是列表(quote as) 'as 计算为一个符号,但它本身不是一个符号)。因此,您的宏真的是一样的:

(define-syntax for
  (syntax-rules ()
    ((_ list (quote as) element body ...)
     (map (lambda (element)
            body ...)
          list))))

其中quoteas是可以匹配任何内容的模式变量。

如uselpa的回答中所述,要求使用与书面as完全相同的正确方法是使用文字列表:

(define-syntax for
  (syntax-rules (as)
    ((_ list as element body ...)
     (map (lambda (element)
            body ...)
          list))))

或者,如果您真的很虐待狂并且想让用户用as引用,请执行以下操作:

(define-syntax for
  (syntax-rules (quote as)
    ((_ list 'as element body ...)
     (map (lambda (element)
            body ...)
          list))))

(是的,您甚至可以将文字列表更改为'as而不是我所拥有的(quote as) ,但这只会使您的宏不可读。请勿这样做。:-P)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM