根据文档,eval和eval-syntax的行为与eval enriches the input syntax不同。
如果顶层表单是一个语法对象,其数据不是已编译的形式,那么它的词法信息在被发送到计算处理程序之前就得到了丰富:就像eval一样,除了stx必须是一个语法对象之外,它的词法上下文在传递给计算处理程序之前并不丰富。
我很难理解这意味着什么。我给人的印象是,在某种程度上涉及到名称空间,但我无法想出一个示例程序,在这个示例程序中,eval和eval语法的行为方式有所不同。(当给定语法对象时。)
那么,eval和eval-syntax有什么不同,或者至少可以给我一个示例程序,显示他们的行为不同?
发布于 2015-08-18 08:03:16
下面是一个示例交互,它显示了他们的不同行为:
Welcome to Racket v6.2.900.10.
-> (define ns (make-base-namespace)) ; set up namespace ns
-> (eval '(require racket/vector) ns) ; bring in vector-map into ns
-> (module a racket/base
(define stx #'(vector-map + #(1 2) #(3 4))) ; no vector-map here
(provide stx))
-> (require 'a)
-> (eval stx ns)
'#(4 6)
-> (eval-syntax stx ns)
; vector-map: undefined;
; cannot reference undefined identifier
; [,bt for context]这表明namespace-syntax-introduce在eval情况下使用具有向量绑定的命名空间应用于语法对象stx,这就是vector-map应用程序成功的原因。
在eval-syntax情况下,语法对象没有vector-map的词法信息,也没有名称空间引入,因此会导致错误。
请注意,您需要模块来显示这种差异,而不是语法对象的顶级定义,因为顶级绑定是特殊的。请参阅namespace-syntax-introduce中的此位
附加上下文被语法对象的词法信息中的任何现有顶级绑定覆盖。
您可以在模块中获得类似的行为:
#lang racket/base ; racket/base does not include racket/vector
(define ns (make-base-namespace)) ; Create Namespace
(eval #'(require racket/vector) ns) ; Load racket/vector into ns
(define stx #'(vector-map + #(1 2) #(3 4)))
(eval stx ns) ; => '#(4 6)
(eval-syntax stx ns) ; => ERROR!发布于 2015-08-18 15:09:07
下面是Asumu答案底部的程序的二重性:
#lang racket/base
(require racket/vector) ; adds vector-map to lexical scope
; use vector-map from lexical scope
(eval-syntax #'(vector-map + #(1 2) #(3 4))) ; => #(4 6)
; vector-map not in dynamic scope
; (make-base-namespace == racket/base)
(eval '(vector-map + #(1 2) #(3 4)) (make-base-namespace))
; => ERR: vector-map: undefined发布于 2015-08-18 13:22:31
这里的关键字是“充实”。docs说,namespace-syntax-introduce被eval用来丰富语法对象:
(namespace-syntax-introduce stx) → syntax?
Returns a syntax object like stx, except that the current namespace’s bindings
are included in the syntax object’s lexical information (see Syntax Objects). 这意味着一个示例是由一个语法对象stx提供的,它引用了当前命名空间中的绑定,其中调用了eval,而在构造语法对象的地方,该绑定不可用。这正是Asumu的例子。
以下是我对“丰富顶层形式”的理解:
(define (enrichen-top-level-form top-level-form)
; see docs for eval
(define introduce namespace-syntax-introduce)
(match top-level-form
[(? syntax? s)
(match (syntax-e s)
[(? compiled-expression? c) c]
[(cons (? sym-or-id? mod?) more)
(define mod (introduce mod?))
(if (bound-identifier=? mod #'module)
(datum->syntax #f (cons mod more))
(introduce s))]
[_ (introduce s)])]
[d (enrichen-top-level-form (datum->syntax #f d #f))]))请参阅这里的更多内容:https://github.com/soegaard/meta/blob/master/expander/expander.rkt#L348
https://stackoverflow.com/questions/32061267
复制相似问题