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

From: Sam TH (samth at ccs.neu.edu)
Date: Sun Mar 11 10:54:29 EDT 2007

Having looked at this in a little more detail, I think I know what the
problem is, but not how to fix it.

When define-struct-type expands, it binds acc1 and mut2, among other
things.  When define-struct-var expands, it is supposed to expand to
macro definitions that refer to acc1 and mut2.  However, those macro
definitions don't contain proper references to those identifiers.
Instead, they refer to some other identically named identifiers.  Why
these identifiers are getting confused, I'm not sure.  But that seems
to be what's going on.

As to why the compile error keeps showing up, I'm not sure.

Hope that helps,

sam th

On 3/11/07, Jens Axel Søgaard <jensaxel at soegaard.net> wrote:
> 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
>
>
>
>


-- 
sam th
samth at ccs.neu.edu


Posted on the users mailing list.