[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