[racket] Getting context info from ellipses pattern vars when calling DATUM->SYNTAX

From: Jon Rafkind (rafkind at cs.utah.edu)
Date: Sun Nov 14 21:57:57 EST 2010

On 11/14/2010 07:52 PM, Sam Tobin-Hochstadt wrote:
> On Sat, Nov 13, 2010 at 5:09 PM, D Marshall <dmarshall207 at gmail.com> wrote:
>> I understand that DATUM->SYNTAX gets it's context
>> information from it's first argument.  I have no problems
>> when using simple (non-ellipses) pattern variables, however,
>> I haven't been unable to get a strictly "ellipses pattern"
>> to work in this context (no pun intended).
> Here are two options:
>
> This is my preference - use the context of the macro application
>     (define-syntax test-this
>       (lambda (x)
>         (syntax-case x ()
>           [(_ a ...)
>              (with-syntax
>               ([form    (datum->syntax x
>                            `(+ ,@(syntax->datum (syntax (a ...)))))])
>               (syntax form))])))
>
> This is also common, but can break in some cases:
>     (define-syntax test-this
>       (lambda (x)
>         (syntax-case x ()
>           [(kw a ...)
>              (with-syntax
>               ([form    (datum->syntax (syntax kw)
>                            `(+ ,@(syntax->datum (syntax (a ...)))))])
>               (syntax form))])))
>
> The reason what you tried to do didn't work is that you need a context
> that is from the context of the macro use.  The rest of the list isn't
> something the programmer originally wrote, but something that was
> generated by your macro, so it doesn't have any useful context.
This works too:

(define-syntax test-this
  (lambda (x)
    (syntax-case x ()
      [(_ a ...)
       (with-syntax
         ([form (datum->syntax (car (syntax->list #'(a ...)))
                               `(+ ,@(syntax->datum #'(a ...))))])
         (syntax form))])))

(let*-values
  ([(one two three) (values 10 20 30)])
  (test-this one two three))

> 60

I thought the reason that using #'(a ...) as the context didn't work was
because #'(a ...) creates a new syntax object by expanding `a' with the
ellipses and so you get the wrong context. But that new syntax object is
composed of objects from the original usage which is why taking the car
works.


Posted on the users mailing list.