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

From: Yin-So Chen (yinso.chen at gmail.com)
Date: Tue Apr 17 19:25:28 EDT 2007

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...
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20070417/0afe55a4/attachment.html>

Posted on the users mailing list.