结构是Racket中的宏吗?

时间:2014-01-05 09:02:19

标签: racket

我记得我在某个地方看过它不是一个宏,并且内置于核心语言中。这样的事情,我不确定,因为我不再记得从哪里读到它。那么,struct是否是Racket中的一个宏?如果没有,为什么它被内置到核心语言中?

4 个答案:

答案 0 :(得分:3)

一个宏; struct.rkt具有

(define-syntax (struct stx)
    (define (config-has-name? config)
      (cond
       [(syntax? config) (config-has-name? (syntax-e config))]
       [(pair? config) (or (eq? (syntax-e (car config)) '#:constructor-name)
                           (eq? (syntax-e (car config)) '#:extra-constructor-name)
                           (config-has-name? (cdr config)))]
       [else #f]))
    (with-syntax ([orig stx])
      (syntax-case stx ()
        [(_ id super-id fields . config)
         (and (identifier? #'id)
              (identifier? #'super-id))
         (if (not (config-has-name? #'config))
             (syntax/loc stx
               (define-struct/derived orig (id super-id) fields  #:constructor-name id . config))
             (syntax/loc stx
               (define-struct/derived orig (id super-id) fields . config)))]
        [(_ id fields . config)
         (identifier? #'id)
         (if (not (config-has-name? #'config))
             (syntax/loc stx
               (define-struct/derived orig id fields  #:constructor-name id . config))
             (syntax/loc stx
               (define-struct/derived orig id fields . config)))]
        [(_ id . rest)
         (identifier? #'id)
         (syntax/loc stx
           (define-struct/derived orig id . rest))]
        [(_ thing . _)
         (raise-syntax-error #f
                             "expected an identifier for the structure type name"
                             stx
                             #'thing)]))))

在Racket IDE中,您可以使用Open Defining File功能查找源代码(如果有)。

答案 1 :(得分:3)

当我之前回答时,看起来我误解了这个问题。所以这是对这个问题的答案:

结构是内置的和原始的;它们是实施的基础。事实上,大约在2007年,马修弗拉特评论说,在PLT计划中(因为当时知道球拍),从某种意义上讲,一切都是结构:

  

>在2007年5月31日星期四16:45:25 -0700,YC写道:
  >出于好奇 - PLT计划实际上使用结构作为基础   >复合类型,即在struct顶部实现闭包/等。

     

我想到它的方式,一切都是结构,但有些东西使用了   特殊情况表示,因为它们足够重要。 (该   极端情况是一个固定的例子。)

     

但同样有效的答案是:不,并非所有化合物类型都使用   与结构构造函数中的值相同的表示形式。

- Source

Start of the thread

答案 2 :(得分:0)

除了usepla的好答案,我想补充一下:

  1. 在Racket文档中,“蓝框”的右上角有一个词组,例如proceduresyntaxstruct代表syntax

  2. 如果你考虑struct做了什么,除了别的以外,它还定义了从结构名称派生的命名函数。因此(struct foo (a b))将定义foo?谓词和访问者foo-afoo-b。普通函数不能定义像这样的新命名事物,因此,它必须是宏。

答案 3 :(得分:0)

通读define-struct.rkt中的实现代码,如果您想手动执行相同的操作,则以下代码是其工作的简化版本。

(define-syntax (struct stx)
;
     ; Function that creates compound names using syntax objects
     (define (make-name id . parts)
       (datum->syntax
         id
         (string->symbol
           (apply string-append
                  (map (lambda (p)
                         (if (syntax? p)
                           (symbol->string (syntax-e p))
                           p))
                        parts)))
         id))
;
  (syntax-case stx ()
;
      ; parse the input and extract the name and variable
      ; this version uses only one variable for simplicity (3)
      [(_ id avar)
;
       ; guard to ensure we have an identifier
       (identifier? #'id) 
;
       ; Create the names (1)
       (let ((? (make-name #'id #'id "?"))
             (v (make-name #'id #'id "-" #'avar)))

         ; Generate code to define the various functions associated with
         ; the new struct (2)
         #`(begin
             (define id (lambda (vx) (list id vx)))
             (define #,? (lambda (x) (eq? (car x) id)))
             (define #,v (lambda (x) (second x)))))]
         ))

1)我们必须创建将要定义的名称:但是我们需要使用语法对象来实现

2)我们生成的代码将定义与全局命名空间中的新对象关联的所有功能

3)在实际版本中,大多数代码都处理可用于结构定义的属性。实际版本还需要处理任意数量的变量和其他形式,默认值等。