[racket] Macro Assistance

From: Gustavo Massaccesi (gustavo at oma.org.ar)
Date: Tue Aug 27 11:00:08 EDT 2013

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.