[plt-scheme] Macro question
Hello,
I'm working on my macro-fu. In my imagination, the form
(bind ([v c1 c2 c3] [v2 c4 c5] [v3 c6]) 'thisisatest)
expands to =>
(let ((v.c1 (vector-ref v 0))
(v.c2 (vector-ref v 1))
(v.c3 (vector-ref v 2))
(v2.c4 (vector-ref v2 0))
(v2.c5 (vector-ref v2 1))
(v3.c6 (vector-ref v3 0)))
(quote thisisatest))
and does; I developed it on lists, and then converted that into a macro. I anticipate using
it in a context where 'v' would be bound to a vector.
If I wrap the returned syntactic value in a 'quote' form
#`(quote (let ...))
I can see that I'm getting back the form that I want (how do you debug macros?). When I
remove the quote
#`(let ...)
I get a complaint about #%app not being bound, in particular with respect to my calls to
'vector-ref'. I've read the docs on this a few times; I don't think it's unclear, but I do think I
don't understand.
As well as the generall call for "help!", suggested rewrites for style, clarity, and grace are
welcome. In the meantime, I'll have a peanut-butter and jelly sandwich and go to bed.
Thanks,
Matt
#cs(module macro mzscheme
(provide bind)
(define-syntax bind
(lambda (e)
(define (make-tuples v* s* s**)
(map (lambda (v s s*)
(map (lambda (tag)
(string->symbol
(string-append
(symbol->string v)
"."
(symbol->string tag)))) (cons s s*)))
v* s* s**))
(define (make-sublists v* tupes)
(apply
append
(map
(lambda (v tup)
(map
(let ([i 0])
(lambda (sym)
(let ([res `(,sym (vector-ref ,v ,i))])
(set! i (add1 i))
res))) tup)) v* tupes)))
(syntax-case e ()
[(_ ((v* s* s** ...) ...) code)
(let* ([subs (syntax-object->datum
(syntax ((v* s* s** ...) ...)))]
[d-v* (map car subs)]
[d-s* (map cadr subs)]
[d-s** (map cddr subs)])
#`(let (#,@(make-sublists
d-v* (make-tuples d-v* d-s* d-s**)))
code)
)])))
)