I'm working on a macro that I'd like to work similar to the 'big-bang'
macro of 2htdp/universe with its various clauses, but something's going on
that I don't understand. At the bottom of this email is some code for a
very simple macro, 'calc', that is not what I'm working on, but exhibits
the puzzling behavior. Here, I'm trying to have an expression like
  (calc (add 5 6) (add 10 9))
expand to a block of some other expressions. Just like the behavior of
big-bang, I'd like to raise an error if (add ...) is used in a context
other than as a clause of 'calc'. But I also don't want it to get confused
with another definition of 'add' in the user code.

With the code below, when run as is, it does what I want - the (calc ...)
expressions - one a top-level expression and the one in (define A (calc
...)) both expand to a (quoted) s-expression (just for debugging purposes),

   (printf "~a~n" (+ 4 5))
   (printf "~a~n" (+ 9 10)))

But, if you uncomment the last two lines, which introduces another
definition of 'add', then the first expression still produces the same as
above, but the expansion of the 'A' expression is just   '(begin). It seems
like the syntax-parse is no longer matching correctly against the (~literal

Actually, 'big-bang' also suffers from this same problem -- if you do
(big-bang 0 (on-tick ...)) as a top-level expression in a file with a
definition of (define on-tick add1), it works fine. But if you put the
'big-bang' inside a define:   (define X (big-bang 0 (on-tick ...))) and
don't change anything else it complains about the on-tick "... keyword
being used as a variable..."

Why does this happen and is there a way to get around this problem -- i.e.
have the behavior of the program below be exactly the same whether there is
a 'define' around the macro use or not?

Thanks very much for any insight!

--- nadeem

#lang racket

(module calc racket
  (provide calc add)

  (require (for-syntax syntax/parse))

  (define-for-syntax out-of-context (lambda (stx) (raise-syntax-error #f
"used out of context" stx)))
  (define-syntax add out-of-context)

  (define-for-syntax (process-clauses clauses)
    (syntax-parse clauses
        [(((~literal add) x y) cs ...) #`((printf "~a~n" (+ x y ))
                                          #,@(process-clauses #'(cs ...) ))]
        [(c cs ...) (process-clauses #'(cs ...))]   ; skip unexpected
clauses for now
        [_ #'()]))

  (define-syntax (calc stx)
    (syntax-parse stx
      [(calc c ...)
       (let ([adds (process-clauses #'(c ...))])
         #`'(begin #,@adds))])))

(require 'calc)

; (expression 1)
(calc (add 4 5)
      (sub 10 7)
      (add 9 10))

; (expression 2)
(define A
  (calc (add 4 5)
        (sub 10 7)
        (add 9 10)))
A  ; see what A ends up being

; uncomment these to see different output from the preceding expressions:
;(define (add x) (add1 x))
;(add 6)

You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to