在阶段 0 中查看阶段 1 计算的结果

See the results of phase 1 computation in phase 0

假设我在 Racket 中有一些具有非平凡 define "override" 的模块。 "override" 收集有关过程主体的信息并将其存储到映射中(在 编译 阶段)。现在我需要在 runtime 阶段使用收集的信息。直截了当的方法似乎行不通:

#lang racket

(require (for-syntax racket))

(define-for-syntax map-that-should-be-used-in-phase-0 (make-hash))
(define-for-syntax (fill-in-useful-information n) (hash-set! map-that-should-be-used-in-phase-0 n n))

; Suppose that some useful information is collected here and stored into a map
(define-syntax (fill-in-map stx)
  (begin
    (fill-in-useful-information 1)
    (fill-in-useful-information 2)
    (syntax/loc stx (displayln "OK, the map is filled, but I cannot see it here"))))

(define-syntax (print-that-map stx)
  (syntax/loc stx (displayln map-that-should-be-used-in-phase-0))) ; <-- This can not be compiled

(fill-in-map)
(print-that-map)

我可以用 Racket 做吗?如果是那么如何?任何提示将不胜感激!

无法编译引用变量的标识符,但可以编译它引用的值,只要它是 Racket 提供的内置数据结构之一,只要它是 immutable。

您可以使用 quasisyntaxunsyntax 将散列 table 值粘贴到语法对象中。

> (quasisyntax (foo #,(hash 'a 4 'b 16)))
#<syntax:5:15 (foo #hash((a . 4) (b . 16)))>

您可以做同样的事情来从编译时到 运行 时进行单向通信。

(define-for-syntax (hash->immutable-hash hsh)
  (make-immutable-hash (hash->list hsh)))

(define-syntax (print-that-map stx)
  (quasisyntax/loc stx (displayln #,(hash->immutable-hash map-that-should-be-used-in-phase-0))))