我做了这个:
#lang racket
(define-syntax-rule (macro-expansion-seconds)
(current-seconds))
这个是哪个
> (macro-expansion-seconds)
1639244531
> (macro-expansion-seconds)
1639244532
> (macro-expansion-seconds)
1639244533
它在扩展时用(current-seconds)
替换(macro-expandsion-seconds)
,并且每次仍对该形式求值。
但是,我如何使它在扩展时评估(current-seconds)
,然后执行此操作?
> (macro-expansion-seconds)
1639244533
> (macro-expansion-seconds)
1639244533
> (macro-expansion-seconds)
1639244533
我知道在这种情况下,我可以做这个
(define macro-expansion-seconds
(current-seconds))
和这个
> macro-expansion-seconds
1639244766
> macro-expansion-seconds
1639244766
> macro-expansion-seconds
1639244766
(名称不再有意义(
但我正试图弄清楚宏是如何工作的,并认为这将是一个简单的例子,可以帮助我弄清楚更难的宏。
最简单的方法是:
#lang racket
(begin-for-syntax
(define the-time (current-seconds)))
(define-syntax (macro-expansion-seconds stx)
(datum->syntax stx the-time))
(macro-expansion-seconds)
(macro-expansion-seconds)
(macro-expansion-seconds)
这里begin-for-syntax
告诉扩展器以下表达式将在编译时求值。因此,the-time
的值将是一个数字。然后,宏需要将数字(这是一个基准(转换为一段语法。这就是datum->syntax
的工作。