简体   繁体   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))))

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

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

My question is why the symbol 'in can pattern the symbol 'as ? 我的问题是,为什么“中的符号可以将符号”表示为? The symbol 'in isn't a only pattern with 'in? “ in”符号不是“ in”的唯一模式吗?

In the Racket doc, at some point it says 在球拍文档中, 有时会说

The template is used in place of a form that matches the pattern, except that each instance of a pattern variable in the template is replaced with the part of the macro use the pattern variable matched. 模板用来代替与模式匹配的形式,只是模板中每个模式变量实例被替换为使用匹配的模式变量的宏部分。

which makes me think that the 'as symbol is simply ignored. 这让我认为'as符号被忽略了。 And indeed, this 确实,这

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

works just as well. 效果也一样。

To get the behaviour you want, use 要获得所需的行为,请使用

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

then 然后

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

but

>  (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))

Macro patterns are not evaluated. 不评估宏模式。 In particular, 'as is not a symbol. 特别地, 'as 不是符号。 It is simply the list (quote as) . 它只是列表(quote as) ( 'as evaluates to a symbol, but it isn't by itself a symbol.) Thus, your macro is really the same as: 'as 计算为一个符号,但它本身不是一个符号)。因此,您的宏真的是一样的:

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

where quote and as are pattern variables that can match anything whatsoever. 其中quoteas是可以匹配任何内容的模式变量。

As mentioned in uselpa's answer, the correct way to require the use of as exactly as written is to use the literal list: 如uselpa的回答中所述,要求使用与书面as完全相同的正确方法是使用文字列表:

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

Or, if you're really sadistic and want to make the user quote the as , do this: 或者,如果您真的很虐待狂并且想让用户用as引用,请执行以下操作:

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

(Yes, you can even change the literal list to be 'as instead of (quote as) as I have it, but that just makes your macro unreadable. Don't do that. :-P) (是的,您甚至可以将文字列表更改为'as而不是我所拥有的(quote as) ,但这只会使您的宏不可读。请勿这样做。:-P)

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

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