假设我有一个函数first-value
,它接受一个值并返回一个忽略其输入并返回原始值的函数:
(: first-value (All (A) (-> A (All (B) (-> B A)))))
(define ((first-value a) b)
a)
如果我在REPL中检查此函数的类型,我发现没有任何意外:
> first-value
- : (All (A) (-> A (All (B) (-> B A))))
#<procedure:first-value>
但是,如果我调用该函数,返回函数的类型看起来有点奇怪:
> (first-value 'foo)
- : (All (g3743) (-> g3743 'foo))
#<procedure>
将B
类型变量替换为gensym。这种情况有什么特别的原因吗?我使用的是Racket 6.1.1
答案 0 :(得分:0)
在形式语法中,符号可以被其他符号替换。如果明确的终端符号被另一个终端替换,如B
替换为g3743
,则相当于重命名。
由于B
的宏观扩展期间无法确定(define ((first-value...
将会是什么gensym
,因此define
避免了未来的模糊或冲突[记住gensym
是一种特殊形式/宏]。
请注意,宏扩展可以在另一个宏扩展中发生,B
允许(first-value 'foo)
中的B
与(first-value 'bar)
中的 (myMacro (first-value 'foo)
(first-value 'bar))
不同在{外部'扩展期间{{1}},例如:
{{1}}