[racket] Macro Assistance

From: Chad Albers (calbers at neomantic.com)
Date: Wed Aug 28 20:42:07 EDT 2013

Thanks for everyone's advice.  I think I will take it and find another
solution.  Thanks!
--
Chad Albers


On Wed, Aug 28, 2013 at 12:00 AM, Gustavo Massaccesi <gustavo at oma.org.ar> wrote:
> Generally these kinds of macros are not a good idea, because it's
> difficult to combine them with other macros. It's probably better to
> use a syntax-parameter like the suggestion in the other message.
>
> The problem in your macro is that with syntax-case can't search bar
> when it's nested at any deep level. It only looks for it in a specific
> position. To search at any level of parenthesis nesting you should
> create an auxiliary function that analyzes recursively the expression,
> and then reconstruct the new version.
>
> ;----------------
> #lang racket
>
> (define-syntax (define-foo stx)
>   (define (replace-bar stx)
>     (syntax-case stx (bar)
>       [(bar . body)
>        (syntax (+ 3 . body))]
>       [(proc other . rest)
>        (with-syntax ([new-other (replace-bar #'other)])
>          (syntax (proc new-other . rest)))]))
>   (syntax-case stx ()
>     [(_ (name param) body)
>      (with-syntax ([new-body (replace-bar #'body)])
>        (syntax (define (name param) new-body)))]))
>
> (define-foo (foof env)
>   (displayln (bar (+ 1 2))))
>
> (foof #f) ;==>6
>
> (define-foo (foog env)
>   (displayln (+ (bar (- 1 (+ 1 2))) 15)))
>
> (foog #f) ;==>16
> ;----------------
>
> This only search for bar in the first argument branch. So
> (define-foo (foog env) (+ (bar 1) 2)) ; works but
> (define-foo (foog env) (+ 2 (bar 1))) ; don't.
>  It's not difficult to extend the idea to handle this kind of cases.
>
> If you want to do more complex transformations with the code between
> define-foo and bar (body1 in your code), then you will need a more
> complex macro.
>
> Gustavo
>
>
> On Tue, Aug 27, 2013 at 5:33 AM, Chad Albers <calbers at neomantic.com> wrote:
>> I'm still trying to grok macros - which are amazing, but hard.  I'd like to
>> know if it is possible capture part of the following expression
>>
>> (display (+ 2 (bar (+ 1 2))))
>>
>> if "bar" is a literal in the macro, I would like to capture body0 as (+ 1 2)
>> and body1 as (display (+ 2 ...)).
>>
>> This is a totally artificial example.
>>
>> Here's what I have:
>>
>> (define-syntax (define-foo stx)
>>   (syntax-case stx (bar)
>>     ([_ (name param) (body1 (bar . body0))]
>>      (syntax (define (name param)
>>                (body1 (+ 3 . body0)))))))
>>
>> (define-foo (foof env)
>>                 (display (bar (+ 1 2))))
>>
>> This works...and expands to.
>>
>> (define (foof env)
>>    (display (+ 3 (- 1 (+ 1 2)))))
>>
>> (Note that -1 has been substitute for the "bar" literal").
>>
>> This expression fails with "bad syntax"
>>
>> (define-foo (foog env)
>>                 (display (+3 (bar (- 1 (+ 1 2))))))
>>
>> I don't seem be to able to capture (display (+3 )) as separate from (bar (-1
>> (+ 1 2)))
>>
>> Is this possible to capture?
>>
>> Thanks for any help and insights into macros
>> Chad
>>
>>
>> ____________________
>>   Racket Users list:
>>   http://lists.racket-lang.org/users
>>

Posted on the users mailing list.