[plt-scheme] Macro question

From: mcj4 at ukc.ac.uk (mcj4 at ukc.ac.uk)
Date: Fri May 23 19:20:12 EDT 2003


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.


#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)
			   (symbol->string v)
			   (symbol->string tag)))) (cons s s*)))
		v* s* s**))

	 (define (make-sublists v* tupes)
	     (lambda (v tup)
		(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**)))

Posted on the users mailing list.