1

我这样做了:

#lang racket

(define-syntax-rule (macro-expansion-seconds)
  (current-seconds))

这是做什么的

> (macro-expansion-seconds)
1639244531
> (macro-expansion-seconds)
1639244532
> (macro-expansion-seconds)
1639244533

它在扩展时替换(macro-expandsion-seconds)(current-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

(名字不再有意义)

但我试图弄清楚宏是如何工作的,并认为这将是一个简单的例子,可以帮助我找出更难的例子。

4

1 回答 1

2

最简单的方法是:

#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

于 2021-12-11T20:59:28.203 回答