[plt-scheme] Dot-notation for structure field access

From: Jens Axel Søgaard (jensaxel at soegaard.net)
Date: Sun Mar 11 10:08:49 EDT 2007

Sam TH skrev:
> I haven't tested this, but you almost certainly need to add
> 
> (require-for-template mzscheme)
> 
> to the `dot' module.

For some reason that's not enough.

The error stems from the line

   (id               #'((make-struct-field-accessor #,acc #,n) 0 #,var))

in register-transformer-builder.

The examples starts with:

    (define-struct-type d c p (x y z) (make-inspector))

which starts this transformer:

(define-syntax (define-struct-type stx)
   (syntax-case stx ()
    <irrelevant clauses>
    ((define-struct-type (descr constr pred super) (field ...) inspector)
     (let-values (((acc mut)
        (apply values (generate-temporaries #'(acc mut)))))
      (register-transformer-builder #'constr #'(field ...) acc mut)
    #`(define-values (descr constr pred #,acc #,mut)
       (let-values
        (((descr constr pred #,acc #,mut)
          (make-struct-type 'descr super
                            #,(length (syntax->list #'(field ...)))
                             0 #f () inspector #f () #f)))
        (values descr constr pred #,acc #,mut)))))))

Then

   (define-struct-var s (c 1 2 add1))

defines s and the s.x, s.y and s.z via:

   (define-syntax (define-struct-var stx)
     (syntax-case stx ()
       ((define-struct-var var (constr expr ...))
        #`(begin
            (define var (constr expr ...))
            #,@((register-lookup #'constr) #'var)))))

The s.x is defined via the procedure registered by:

(define-for-syntax (register-transformer-builder constr fields acc mut)
     (register-add!
      constr
      (lambda (var)
        (let ((n 0))
          (map
           (lambda (field)
             (let ((dotted-var (make-id var field)))
               (begin0
                 #`(define-syntax #,dotted-var
                     (make-set!-transformer
                      (lambda (stx)
                        (syntax-case stx (set!)
                          ((set! id v)
                           #'((make-struct-field-mutator #,mut #,n)
                               #,var v))
                          ((id x (... ...))
                           #'(((make-struct-field-accessor #,acc #,n)
                              #,var) x (... ...)))
                          (id
                           #'((make-struct-field-accessor #,acc #,n) XXX
                              0 #,var))))))
                 (set! n (add1 n)))))
           (syntax->list fields))))))

I have marked the offending line with XXX.

-- 
Jens Axel Søgaard





Posted on the users mailing list.