Oh, wow, that is elegant.

Before seeing your post, I'd worked ahead on my own and came up with
something where the core helper function calls back to the
wrapper-provided higher-order function with a #'(LIST OF PATTEN VARS)
--- which the callee needs to syntax-case back into pattern variables
again:

https://github.com/greghendershott/def-jambda/commit/eda5bf8ce5668e49ba4068c50eab8055e34fcdc7

Although it works, it feels like using a list instead of a struct, and
using (match-define (list ....) x) instead of using struct field
accessors. With similar pros/cons. A con: It's fragile. If the list of
pattern variables were to change someday, it would break in a
less-helpful way. (Changing struct fields would still break, but more
helpfully. Adding a new field wouldn't break, at all.)

And so IIUC a syntax-class is the analog of a struct, for this.

Which was probably spelled out plainly on slide 2 of a presentation I
saw Ryan give years ago. O_o  But if so, at the time I only took away
the sense in which syntax-parse improves parsing details of
syntax-case.  I guess this is one of those cases where I had to try
the more-painful way myself, to be ready to learn/appreciate the
better way.

Cool!



On Wed, Sep 4, 2013 at 11:03 PM, Stephen Chang <stch...@ccs.neu.edu> wrote:
> Could you throw all the common parts into a syntax-class?
>
> That would enable you to put the cond branches in the defns
> themselves, which I agree is better.
>
> Something like this: https://gist.github.com/stchang/6445553
>
> I havent tested extensively but it seems to behave the same as your
> code on a few small examples.
>
> On Wed, Sep 4, 2013 at 8:37 PM, Greg Hendershott
> <greghendersh...@gmail.com> wrote:
>> Given some macros that are wrappers around a core helper function:
>>
>> (define-syntax (wrapper1 stx)
>>   (core #f #f))
>> (define-syntax (wrapper2 stx)
>>   (core #f #t))
>> (define-syntax (wrapper3 stx)
>>   (core #t #f))
>> (define-syntax (wrapper4 stx)
>>   (core #t #t))
>>
>> (define-for-syntax (core stx opt1? opt2?)
>>   (define-syntax-class x ....)
>>   (syntax-parse stx
>>     [(_ pattern )
>>      (with-syntax*
>>        ([ <bunch of pattern variables> ])
>>        ;; Ugly cond using opt1? and opt2
>>        (cond [opt1? (cond [opt2? #'( <use ptn vars> )]
>>                           [else #'( <use ptn vars> )])]
>>              [else (cond [opt2? #'( <use ptn vars> )]
>>                          [else #'( <use ptn vars> )])]))]))
>>
>> Now I want/need to refactor the code. For one thing, some of the
>> wrappers must be in a file with `#lang racket`, and others in another
>> file with `#lang typed/racket`. Plus, the cond stuff is ugly; each
>> wrapper should handle this itself.  And in refactoring, of course I
>> want to D.R.Y. instead of copy pasta.
>>
>> The following seems somewhat better. Have the wrappers supply a
>> "callback" function to the core:
>>
>> ;; wrap12.rkt
>> #lang racket
>> (require "core.rkt")
>> (define-syntax (wrapper1 stx)
>>   (core (lambda (stx <bunch of pattern vars> )
>>           #'( <use ptn vars> ))))
>> .. wrapper2 similar ..
>>
>> ;; wrap34.rkt
>> #lang typed/racket
>> (require "core.rkt")
>> ... wrappers 3 4 similar ..
>>
>> ;; core.rkt
>> (provide core)
>> (define-for-syntax (core stx f)
>>   (define-syntax-class y ....)
>>   (syntax-parse stx
>>     [(_ pattern )
>>      (with-syntax*
>>        ([ <bunch of pattern variables> ])
>>        (f stx <bunch of pattern variables> ))])) ;; give back to the
>> caller and let it make the syntax
>>
>> And now it's easy for them to be in different files. However:
>>
>> 1. Now instead the ugly part is schlepping the pattern variables
>> around (e.g. half dozen function parameters).
>>
>> 2. Pattern variables and templates can't be separated like this and
>> still work, AFAICT.
>>
>> I have a few ideas that I'll go ahead and try, but I wanted to go
>> ahead and post this to see what ideas or advice anyone might have.
>>
>>
>> p.s. In case my question and code sketch here is too abstract, my
>> motivating full example is this:
>>
>> https://github.com/greghendershott/def-jambda/blob/50f6abcb7a64558756dce653c1faac4c012d4167/main.rkt
>> ____________________
>>   Racket Users list:
>>   http://lists.racket-lang.org/users
____________________
  Racket Users list:
  http://lists.racket-lang.org/users

Reply via email to