首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >“and”和“and syntax”之间的区别

“and”和“and syntax”之间的区别
EN

Stack Overflow用户
提问于 2015-08-17 23:23:27
回答 3查看 318关注 0票数 9

根据文档,evaleval-syntax的行为与eval enriches the input syntax不同。

如果顶层表单是一个语法对象,其数据不是已编译的形式,那么它的词法信息在被发送到计算处理程序之前就得到了丰富:就像eval一样,除了stx必须是一个语法对象之外,它的词法上下文在传递给计算处理程序之前并不丰富。

我很难理解这意味着什么。我给人的印象是,在某种程度上涉及到名称空间,但我无法想出一个示例程序,在这个示例程序中,eval和eval语法的行为方式有所不同。(当给定语法对象时。)

那么,evaleval-syntax有什么不同,或者至少可以给我一个示例程序,显示他们的行为不同?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-08-18 08:03:16

下面是一个示例交互,它显示了他们的不同行为:

代码语言:javascript
复制
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-introduceeval情况下使用具有向量绑定的命名空间应用于语法对象stx,这就是vector-map应用程序成功的原因。

eval-syntax情况下,语法对象没有vector-map的词法信息,也没有名称空间引入,因此会导致错误。

请注意,您需要模块来显示这种差异,而不是语法对象的顶级定义,因为顶级绑定是特殊的。请参阅namespace-syntax-introduce中的此位

附加上下文被语法对象的词法信息中的任何现有顶级绑定覆盖。

您可以在模块中获得类似的行为:

代码语言:javascript
复制
#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!
票数 9
EN

Stack Overflow用户

发布于 2015-08-18 15:09:07

下面是Asumu答案底部的程序的二重性:

代码语言:javascript
复制
#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
票数 4
EN

Stack Overflow用户

发布于 2015-08-18 13:22:31

这里的关键字是“充实”。docs说,namespace-syntax-introduceeval用来丰富语法对象:

代码语言:javascript
复制
(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的例子。

以下是我对“丰富顶层形式”的理解:

代码语言:javascript
复制
(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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32061267

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档