[racket] Help with simple macro

From: Harry Spier (vasishtha.spier at gmail.com)
Date: Tue May 22 21:54:30 EDT 2012

Thanks to this Eli, I now see what parameters are.

By chance I also just came across your's, Ryan's and Matthew's article
"Keeping It Clean with Syntax Parameters"
http://www.schemeworkshop.org/2011/papers/Barzilay2011.pdf
that makes crystal clear all the issues about the question I asked.

Cheers,
Harry

On Mon, May 21, 2012 at 10:01 AM, Eli Barzilay <eli at barzilay.org> wrote:
> On Wednesday, Harry Spier wrote:
>> [...]
>> but I've been unable to create a macro to create this form:
>> ---------------------------------------
>> (with-sequence  SOME-SEQUENCE
>> . . . .. . (get-next) .
>>  . . . (get-next) . . . etc.)
>> ---------------------------------------
>>
>> where I don't pass the names of the thunks to test for end of sequence
>> or to get the next item in the sequence, but that they are called
>> "more?" and "get-next" by convention.
>>
>> How would I do this.
>
> Since you're using the name as a function, you can do that easily with
> a parameter:
>
>  (define current-get-next (make-parameter (λ () (error "no next"))))
>  (define (get-next) ((current-get-next)))
>  (define-syntax-rule (with-sequence seq body ...)
>    (let-values ([(more? the-get-next) (sequence-generate seq)])
>      (parameterize ([current-get-next the-get-next])
>        body ...)))
>  (with-sequence '(1 2 3)
>    (list (get-next) (get-next) (get-next)))
>
> [You could also make it appear as a magical binding with an identifer
> macro:
>
>  (define-syntax next
>    (syntax-id-rules ()
>      [(_ x ...) ((get-next) x ...)]
>      [_ (get-next)]))
> ]
>
> This does have some performance penalty though, since each call to
> `get-next' goes through the parameter.  The way to avoid that is to
> switch the parameter to a syntax parameter -- the idea is similar to a
> parameter, except that it's done at the syntax level:
>
>  (require racket/stxparam)
>  (define-syntax-parameter get-next
>    (λ (stx) (raise-syntax-error #f "not in `with-sequence'" stx)))
>  (define-syntax-rule (with-sequence seq body ...)
>    (let-values ([(more? the-get-next) (sequence-generate seq)])
>      (syntax-parameterize ([get-next (make-rename-transformer #'the-get-next)])
>        body ...)))
>  (with-sequence '(1 2 3)
>    (list (get-next) (get-next) (get-next)))
>
> --
>          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
>                    http://barzilay.org/                   Maze is Life!


Posted on the users mailing list.