[racket] Advice how to refactor code to share pattern variables but split out templates?

From: Stephen Chang (stchang at ccs.neu.edu)
Date: Wed Sep 4 23:03:54 EDT 2013

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
<greghendershott at 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

Posted on the users mailing list.