在编写 Racket 宏的上下文中,“3D 语法”是什么意思?
这句话我听过好几次了。包含一次对宏的引用I正在写作。但那是不久前的事了;我修复了它,现在我不记得我最初做错了什么。
另外:是 3D 语法吗always坏的?或者是像eval
(如果你认为你需要使用它,你可能错了,但是有some在专家手中有效使用)?
语法对象通常应该是可序列化的数据 http://docs.racket-lang.org/reference/stxops.html#%28def._%28%28quote._~23~25kernel%29._syntax-e%29%29。 3D 语法削弱了这种条件:它允许我们潜入任意值,而不仅仅是纯数据。这就是使它们成为“3d”的原因:它们是高于您期望从语法对象中获得的常规平面事物的值。
例如,我们可以潜入lambda
values!
#lang racket
(define ns (make-base-namespace))
(define (set-next! n)
(parameterize ([current-namespace ns])
(eval #`(define next #,n)))) ;; <-- 3d-syntax here
(define (compute s)
(parameterize ([current-namespace ns])
(eval s)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define counter 0)
(set-next! (lambda ()
(set! counter (add1 counter))
counter))
(compute '(+ (next)
(next)
(next)
(next)))
这样做通常是一件坏事,因为此类值的存在可能意味着在编译阶段泄漏信息的毫无根据的尝试。结果可能无法单独编译。如果您看到类似于以下内容的错误:
write: cannot marshal value that is embedded in compiled code value
那么这很可能是由于宏生成了一段无法序列化为字节码的 3D 语法。
有时,在极少数情况下,我们确实需要 3D 语法,通常是在动态评估上下文中。举个具体的例子,DrRacket 中的调试器可能想要注释程序的语法,以便函数应用程序直接回调调试器的函数,以便我们可以在程序编辑器中执行交互式代码覆盖着色之类的操作。从这个意义上说,3d 语法可以充当动态评估代码与其周围环境之间的通信通道。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)