[plt-scheme] depth of macro expansion in module during module require?

From: Yin-So Chen (yinso.chen at gmail.com)
Date: Tue Apr 17 20:48:44 EDT 2007

It seems that (provide) is magical?  If I rewrite my form with provide in
main & time-out then I don't need the datum->syntax-object at all, but if I
remove the provides to be outside of syntax block then start, timeout,
interface-version don't work anymore...

(module syntax-util mzscheme
  (provide (all-defined))

  (define-syntax time-out
    (lambda (stx)
      (syntax-case stx ()
        ((_ t)
         #'(begin
             (define timeout t)
             (provide timeout))))))

  (define-syntax main
    (lambda (stx)
      (syntax-case stx ()
        ((_ body ...)
         #'(begin
             (define (start initial-request) body ...)
             (provide start))))))

  (define-syntax servlet
    (lambda (stx)
      (syntax-case stx ()
        ((_ body ...)
           #`(begin
               body ...
               (define interface-version 'v1)
               (provide interface-version)
               )))))
  )

(require syntax-util)

(module webtest1 mzscheme
  (require syntax-util)
  (servlet
   (time-out +inf.0)
   (main `(p "hello world"))
   )
  )

(require webtest1)

timeout
(start null)
interface-version

On 4/17/07, Yin-So Chen < yinso.chen at gmail.com> wrote:
>
> Hi Jens -
>
> thanks for the quick reply.  After some more researching plus looking at
> your code I realized where my mistakes are - I thought symbols in a syntax
> expands out to itself, but apparently this is not the case (hence my problem
> has nothing to do with module/macros).  Instead, I need to use
> datum->syntax-object to make sure that timeout in syntax equals timeout in
> symbol (BTW - thanks for your example showing below using stx as the context
> syntax... I was scratching my head trying to figure out where I can provide
> a context).
>
> However, looking at your code there are some concepts that I don't
> understand:
>
>    - your code provides syntax name for time-out and main rather than
>    timeout, start, initial-request, and interface-version - why this also works
>    without having to convert them to syntax-object?
>    - how does the nested define-syntax work both in terms of expansion
>    and scoping?
>    - Aesthetics and styles aside - is there a reason for nested
>    define-syntax?  (It looks cool to learn, but I came from the C world where
>    definitions belong on top level, so want to know why and how I can think in
>    this fashion)
>
> Below is what I have right now that works... yours seem shorter ;)
>
> (module syntax-util mzscheme
>   (provide (all-defined))
>
>   (define-syntax time-out
>     (lambda (stx)
>       (syntax-case stx ()
>         ((_ t)
>          (with-syntax ((timeout (datum->syntax-object stx 'timeout)))
>            #'(define timeout t))))))
>
>   (define-syntax main
>     (lambda (stx)
>       (syntax-case stx ()
>         ((_ body ...)
>          (with-syntax ((start (datum->syntax-object stx 'start))
>                        (initial-request (datum->syntax-object stx
> 'intial-request)))
>            #'(define (start initial-request)
>                body ...))))))
>
>   (define-syntax servlet
>     (lambda (stx)
>       (syntax-case stx ()
>         ((_ body ...)
>          (with-syntax ((interface-version (datum->syntax-object stx
> 'interface-version)))
>            #'(begin
>                body ...
>                (define interface-version 'v1)
>                (provide (all-defined)))))))))
>
> (module webtest1 mzscheme
>   (require syntax-util)
>   (servlet
>    (time-out +inf.0)
>    (main '(p "hello world"))))
>
> (require webtest1)
>
> timeout ; => +inf.0
> interface-version ; =>  'v1
> (start null) ; => '(p "hello world")
>
> Thanks,
> yinso
>
>
> On 4/17/07, Jens Axel Søgaard < jensaxel at soegaard.net> wrote:
> >
> > Hi Yin-So,
> >
> > Here is one way to do it:
> >
> > (module syntax-util mzscheme
> >    (provide (all-defined))
> >
> >    (define-syntax servlet
> >      (lambda (stx)
> >        (syntax-case stx ()
> >          ((_ body ...)
> >           (with-syntax ([time-out (datum->syntax-object stx 'time-out)]
> >                         [main     (datum->syntax-object stx 'main)])
> >             #`(begin
> >                 (define-syntax (time-out stx)
> >                   (syntax-case stx ()
> >                     ((_ value)
> >                      #'(begin
> >                          (define timeout value)
> >                          (provide timeout)))))
> >                 (define-syntax (main stx)
> >                   (syntax-case stx ()
> >                     [(_ body1 (... ...))
> >                      #'(define start
> >                          (lambda (initial-request)
> >                            body1 (... ...)))]))
> >                 body ...
> >                 (define interface-version 'v1)
> >                 (provide (all-defined))
> >                 ))))))
> >    )
> >
> >     (require syntax-util)
> >
> >   (module webtest1 mzscheme
> >     (require syntax-util)
> >     (servlet
> >      (time-out +inf.0)
> >      (main `(p "hello world"))
> >      ))
> >
> >   (require webtest1)
> >
> >   timeout
> >
> >
> > I moved the definitions of time-out and main into the expansion of
> > servlet, since they need to be in the scope of the forms of body ... .
> > Note that when expanding into ... one needs to write (... ...).
> >
> > Also, to provide a name such as timeout, the provide form must have
> > the same syntactic context as the definition. The easiest way to ensure
> > this is, to put a provide-clause next to the definition.
> >
> > --
> > Jens Axel Søgaard
> >
> >
> >
> > --
> > Jens Axel Søgaard
> >
> >
>
>
> --
> http://www.yinsochen.com
> ...continuous learning...
>



-- 
http://www.yinsochen.com
...continuous learning...
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20070417/f89ac268/attachment.html>

Posted on the users mailing list.