[racket] ... in macro defining macros?

From: Jon Rafkind (rafkind at cs.utah.edu)
Date: Sat Aug 4 00:08:17 EDT 2012

I think its explained here

http://docs.racket-lang.org/reference/stx-patterns.html?q=ellipses#(form._((lib._racket/private/stxcase-scheme..rkt)._syntax)) <http://docs.racket-lang.org/reference/stx-patterns.html?q=ellipses#%28form._%28%28lib._racket/private/stxcase-scheme..rkt%29._syntax%29%29>

at (ellipses stat-template), although I find the explanation confusing. Probably an example of (... ...) would be useful there.

On 08/03/2012 09:51 PM, Nick Sivo wrote:
> Hi Jon,
>
> Thanks, that works perfectly!
>
> Did I miss that somewhere in the documentation?  I don't recall seeing
> an example of it.
>
> Best,
> Nick
>
> On Thu, Aug 2, 2012 at 11:55 PM, Jon Rafkind <rafkind at cs.utah.edu> wrote:
>> To match a literal ellipses in syntax-parse use #:literal [(ellipses ...)] and match on the term `ellipses', then to use a literal ellipses in the template use (... ...) instead of just ...
>>
>> It looks like you only want the latter, so
>>
>> (define-syntax (example stx)
>>   (syntax-parse stx
>>     [(_ name:id) #'(define-syntax (name stx)
>>                               (syntax-parse stx
>>                                  [(_ args (... ...)) #'(args (... ...)))])]))
>>
>> On 08/02/2012 11:30 PM, Nick Sivo wrote:
>>> Hi,
>>>
>>> I'm trying to use ... in the inner macro of a macro defining macro,
>>> but can't figure out the right way to escape it.
>>>
>>> Here's a minimal (pointless) example:
>>>
>>> (require (for-syntax syntax/parse))
>>>
>>> (define-syntax (example stx)
>>>   (syntax-parse
>>>    stx
>>>    ;#:literals (...) ; Doesn't help :(
>>>    [(_ name:id)
>>>     #'(define-syntax (name stx)
>>>         (syntax-parse
>>>          stx
>>>          [(_ args ...) #'(args ...)]))]))
>>>
>>> The goal is to have (example invisible) define a macro called
>>> invisible that erases itself.
>>>
>>> Any ideas?  The full code I'm trying to enable follows below if you'd
>>> like more context.
>>>
>>> Thanks,
>>> Nick
>>>
>>> #lang racket
>>>
>>> (require (for-syntax syntax/parse)
>>>          racket/splicing)
>>>
>>> ;;;
>>> ;;; Procedure Application
>>> ;;;
>>>
>>> (define arc-nil #f)
>>>
>>> (define-syntax (arc-#%app stx)
>>>   (syntax-parse
>>>    stx
>>>    [(_ fn:expr arg:expr)
>>>     #'(let ([efn fn])
>>>         (cond [(procedure? efn) (#%app efn arg)]
>>>               [(pair? efn) (#%app list-ref efn arg)]
>>>               [(string? efn) (#%app string-ref efn arg)]
>>>               [(hash? efn) (#%app hash-ref efn arg arc-nil)]
>>>               [else (#%app efn arg)]))]
>>>    [(_ fn:expr arg1:expr arg2:expr)
>>>     #'(let ([efn fn])
>>>         (if (hash? efn)
>>>             ; Have to use the lamda in case arg2 is a function
>>>             ; See hash-ref docs for more info
>>>             (#%app hash-ref fn arg1 (lambda () arg2))
>>>             (#%app fn arg1 arg2)))]
>>>    [(_ args ...)
>>>     #'(#%app args ...)]))
>>>
>>> ; This allows cross module mutation of globals
>>> (define-syntax (declare-with-set-transformer stx)
>>>   (syntax-parse
>>>    stx
>>>    ;#:literals (...) ; Doesn't help :(
>>>    [(_ var:id)
>>>     #'(declare-with-set-transformer var (gensym 'unintialized))]
>>>    [(_ var:id init-val:expr)
>>>     (let ([store-name (gensym (syntax->datum #'var))])
>>>       #`(begin
>>>           (define #,store-name init-val)
>>>           (splicing-let ([set (lambda (val)
>>>                                 (set! #,store-name val))])
>>>             (define-syntax var
>>>               (make-set!-transformer
>>>                (lambda (stx)
>>>                  (syntax-case stx (set!)
>>>                    [(set! id val) #'(set val)]
>>>                    ; Uses Racket's #%app, which doesn't work for arc
>>>                    [(id . args) #'(#,store-name . args)] ; function application
>>>                    ; Obviously invalid syntax
>>>                    ;[(id . args) #'(arc-#%app #,store-name . args)]
>>>                    ; Errors because ... isn't recognized as a literal
>>>                    ;[(id args ...) #'(arc-#%app #,store-name args ...)]
>>>                    [id (identifier? #'id) #'#,store-name])))))))]))
>>>
>>> ; Demo of what I'm looking for
>>> (define test (make-hash))
>>> (hash-set! test 'key 'value)
>>> (displayln (arc-#%app test 'key))
>>>
>>> ; Example of what doesn't work right now
>>> (declare-with-set-transformer test2 (make-hash))
>>> (hash-set! test2 'key 'value)
>>> (displayln (test2 'key))
>>> ____________________
>>>   Racket Users list:
>>>   http://lists.racket-lang.org/users
>> ____________________
>>   Racket Users list:
>>   http://lists.racket-lang.org/users

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20120803/fb9ffd61/attachment.html>

Posted on the users mailing list.