[plt-scheme] auxiliary macros
Vlado, you can, however, choose a different piece of context syntax
for the introduction of the yield binding, namely, one from the
scope you really want:
(define-syntax (define/y stx)
(syntax-case stx ()
[(_ (name arg ...) body0 body ...)
(with-syntax ((yield-name (datum->syntax-object #;stx (syntax
body0) 'yield)))
(syntax
(define (name arg ...)
(define (yield-name x)
(control resume-here
(set! name
(lambda ()
(prompt (resume-here 'dummy))))
x))
(prompt body0 body ...))))]))
If you now target this mini-language with a macro, the non-hygienic
binding is introduced properly, e.g.,
(define-syntax foo
(syntax-rules ()
((_ (name arg ...) body ...) (define/y (name arg ...) body ...))))
(foo (bar) (printf "hello world\n") (yield 1) (yield 2) 'finished)
(list (bar) (bar) (bar) (bar))
-- Matthias
On Aug 4, 2007, at 10:58 AM, Ryan Culpepper wrote:
> On Fri, 2007-08-03 at 13:35 +0100, Vladimir Zlatanov wrote:
>>
>> 2. How can I use the macro system to eliminate the
>> 'yield-name' part
>> of the macro?
>>
>> One solution that works, but I do have a few problems with it.
>> I had to break the hygiene, which in this case might not be that bad,
>> but it is not nice. More worringly for me, I'm not sure why does it
>> really work the way it works. It is a problem with my
>> understanding of
>> macros, but that might pass with time =)
>>
>> What would be a hygienic solution?
>
> One problem with using 'datum->syntax-object' to introduce identifiers
> (breaking hygiene) is that it often breaks down when you write another
> macro that expands into the first one.
>
> For example, here's a trivial macro:
>
> (define-syntax define-gen
> (syntax-rules ()
> [(define-gen (name . args) . body)
> (make-gen (name . args) . body)]))
>
> Then use it:
>
> (define-gen (make-step)
> (yield 1)
> (yield 2)
> (yield 3)
> 'finished)
> (define step (make-step))
> (step) ;; produces error: undefined identifier 'yield'
>
> Why? The 'make-gen' identifier produced by 'define-gen' had a mark on
> it, so the introduced 'yield' identifier had a mark on it, so it
> didn't
> bind the original, unmarked occurrences of 'yield'.
>
> One nice way to solve this problem is to use syntax parameters. There
> was a thread on this list about them about a year ago, and I wrote
> up a
> summary here:
>
> http://macrologist.blogspot.com/2006/04/macros-parameters-binding-
> and.html
>
> There's more information in the Help Desk: search for
> 'syntax-parameterize'.
>
> Ryan
>
>
>>
>> ===========================
>> (require (lib "control.ss"))
>>
>> (define-syntax (make-gen stx)
>> (syntax-case stx ()
>> [(mkg (name arg ...) body ...)
>> (syntax-case (datum->syntax-object (syntax mkg) 'yield) ()
>> [yield (syntax
>> (define (name arg ...)
>> (define (control-state) body ...)
>> (define (yield value) (control resume-here (set!
>> control-state resume-here) value))
>> (lambda () (prompt (control-state)))))])]))
>>
>> (make-gen (make-step)
>> (yield 1)
>> (yield 2)
>> (yield 3)
>> 'finished)
>>
>> (define step (make-step))
>>
>> (step)(step)(step)(step)(step)
>>
>> ===========================
>>
>> _________________________________________________
>> For list-related administrative tasks:
>> http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>
> _________________________________________________
> For list-related administrative tasks:
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme