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

TJ tjay.dreaming at gmail.com
Tue Apr 17 02:50:32 EDT 2007


On 4/17/07, Marc Feeley <feeley at iro.umontreal.ca> wrote:
> 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))

It doesn't work, because define-only is defined so that the expanded
form becomes (simplified):

(begin
  (define mkcounter #f)
  (let ((tmp #f) ...)
     ((lambda ()
         (define-structure counter v) ;; Invisible from the top-level.
         (let ()
            (define mkcounter
               (lambda () (make-counter 0))))
        (set! tmp mkcounter))) ; mkcounter refers to the top-level
binding here, as the internal mkcounter has been wrapped up in a let.
     (set! mkcounter tmp)))

> 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

I had to remove the (##namespace...) clauses at the beginning of
syntax-case.scm because psyntax73.ss needed some procedures defined in
syntax-case.scm which were, I presume, hidden by the namespace
declarations. Also, I had to remove the (let () ...) clause
surrounding most of psyntax73.ss, so that code outside of the let
could actually use the stuff defined in psyntax73.ss. After removing
the let I also had to move all the (define-syntax ...) forms to the
front, before the (define ...)'s.

After that my code worked.

Here's my working code:

;; Begin code ------

(include "~/syntax-case.scm") ;; Edited syntax-case.scm
(include "~/psyntax73.ss")     ;; Edited psyntax73.ss

(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) ...))))))))

(define-only (mkcounter inc! val)
   (my-define-structure (counter v))
   (define mkcounter
     (lambda () (make-counter 0)))
   (define inc!
     (lambda (c)
       (set-counter-v! c
                       (+ 1 (counter-v c)))))
   (define val counter-v))

;; Do stuff here...

;; End code ------

With these in my gambcini.scm:

(load "~/syntax-case.scm")
(load "~/gambc-4.0b22-charsize4/misc/psyntax73.ss")

So basically it works, but only after tweaking around.

TJ



More information about the Gambit-list mailing list