[gambit-list] Syntax-case, define-structure, and internal defines...

Marc Feeley feeley at iro.umontreal.ca
Mon Apr 16 16:14:07 EDT 2007


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

 From misc/syntax-case.scm:

; Note that Gambit's normal parser processes the
; input after expansion by the syntax-case expander.  Since the
; syntax-case expander does not know about Gambit's syntactic
; extensions (like DSSSL parameters) some of the syntactic
; extensions cannot be used.

One of those Gambit extensions is define-structure.  So the portable  
syntax-case expander thinks that

    (define-structure ...)

is a function call, so it thinks the "define" that follows it is  
illegal.

I think this should work:

(define-only (mkcounter inc! val)
     (define-structure counter v) ;; Invisible from the top-level.
     (let ()
       (define mkcounter
         (lambda () (make-counter 0)))
       (define inc!
         (lambda (c)
           (counter-v-set! c
                           (+ 1 (counter-v c)))))
       (define val counter-v)
       #f))

Also, you can get around this problem by using your own definition  
for define-structure, for example this one from misc/psyntax73.scm:

(define-syntax define-structure
   (lambda (x)
     (define construct-name
       (lambda (template-identifier . args)
         (datum->syntax-object
           template-identifier
           (string->symbol
             (apply string-append
                    (map (lambda (x)
                           (if (string? x)
                               x
                               (symbol->string (syntax-object->datum  
x))))
                         args))))))
     (syntax-case x ()
       ((_ (name id1 ...))
        (andmap identifier? (syntax (name id1 ...)))
        (with-syntax
          ((constructor (construct-name (syntax name) "make-" (syntax  
name)))
           (predicate (construct-name (syntax name) (syntax name) "?"))
           ((access ...)
            (map (lambda (x) (construct-name x (syntax name) "-" x))
                 (syntax (id1 ...))))
           ((assign ...)
            (map (lambda (x)
                   (construct-name x "set-" (syntax name) "-" x "!"))
                 (syntax (id1 ...))))
           (structure-length
            (+ (length (syntax (id1 ...))) 1))
           ((index ...)
            (let f ((i 1) (ids (syntax (id1 ...))))
               (if (null? ids)
                   '()
                   (cons i (f (+ i 1) (cdr ids)))))))
          (syntax (begin
                    (define constructor
                      (lambda (id1 ...)
                        (vector 'name id1 ... )))
                    (define predicate
                      (lambda (x)
                        (and (vector? x)
                             (= (vector-length x) structure-length)
                             (eq? (vector-ref x 0) 'name))))
                    (define access
                      (lambda (x)
                        (vector-ref x index)))
                    ...
                    (define assign
                      (lambda (x update)
                        (vector-set! x index update)))
                    ...)))))))


Marc



On 16-Apr-07, at 1:20 PM, TJ wrote:

> I have a macro defined thus:
>
> (define-syntax define-only
>   (lambda (exp)
>     (syntax-case exp ()
>       ((_ (n ...) e ...)
>        (with-syntax (((tmp ...)
>                       (generate-temporaries (syntax (n ...)))))
>          (syntax
>           (begin (define n #f) ...
>                  (let ((tmp #f) ...)
>                    ((lambda ()
>                       e ...
>                       (set! tmp n) ...))
>                    (set! n tmp) ...))))))))
>
> Which, if it works, would enable me to do the following:
>
> (define-only (mkcounter inc! val)
>     (define-structure counter v) ;; Invisible from the top-level.
>     (define mkcounter
>       (lambda () (make-counter 0)))
>     (define inc!
>       (lambda (c)
>         (counter-v-set! c
>                         (+ 1 (counter-v c)))))
>     (define val counter-v))
>
> But which, unfortunately, gives me the following:
>
> *** ERROR -- invalid context for definition (define mkcounter (lambda
> () (make-counter 0)))
>
> I suspected that perhaps (define...)'s were not allowed after
> (define-structure...)'s. So I did this:
>
> (pp (lambda () (define-structure test a) 'done))
>
> Which prints the following:
>
> (lambda ()
>   (letrec ((##type-1-test
>             (##structure
>              ##type-type
>              (##make-uninterned-symbol "##type-1-test")
>              'test
>              8
>              #f
>              '#(a 0 #f)))
>            (make-test (lambda (p1) (##structure ##type-1-test p1)))
>            (test? (lambda (obj) (##structure-direct-instance-of? obj
> (##type-id ##type-1-test))))
>            (test-a (lambda (obj) (##direct-structure-ref obj 1
> ##type-1-test test-a)))
>            (test-a-set!
>             (lambda (obj val) (##direct-structure-set! obj val 1
> ##type-1-test test-a-set!))))
>     'done))
>
> Which makes me wonder why my macro doesn't work. After all
> (define...)'s are allowed at the beginning of a letrec's body, no?
>
> TJ
> _______________________________________________
> Gambit-list mailing list
> Gambit-list at iro.umontreal.ca
> https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.3 (Darwin)

iD8DBQFGI9kQ//V9Zc2T/v4RAt06AJ4sSuBibnv54krgV5fgLrShtzUiQQCfQqCq
Bs8cYZJfp97n652XFU/CxMU=
=yx8C
-----END PGP SIGNATURE-----



More information about the Gambit-list mailing list