[plt-scheme] Macro question
mcj4 at ukc.ac.uk wrote:
> Having the 'vec.name' naming is important to me, both practically and so I understand
> better how to lexically introduce new names into the environment with a macro. However,
> I can certainly work with what you tossed out, and it wins points for clarity.
>
> M
Ok. How's this?
(define-syntax (bind stx)
(syntax-case stx ()
((_ ([v c1 c2 ...] ...) e ...)
(with-syntax ((((v.c1 v.c2 ...) ...)
(datum->syntax-object
stx
(map (lambda (clause)
(map (lambda (x)
(symbol-dot-symbol (car clause) x))
(cdr clause)))
(syntax-object->datum #'((v c1 c2 ...) ...))))))
#'(let-values ([(v.c1 v.c2 ...)
(let ((n (length '(c1 c2 ...))))
(vector->values (vector-take v n)))]
...)
e ...)))))
SYMBOL-DOT-SYMBOL has type (symbol symbol) -> symbol, with the obvious
meaning, and needs to be bound in the transformer environment of BIND.
VECTOR-TAKE is from SRFI 43.
This syntax, unlike the first solution I had, makes an assumption about v in
(bind ([v c1 c2 ...] ...) ...). v must be an identifier that is bound to a
vector. So you couldn't write eg, (bind (((make-vector 5) c1)) ...), but I
guess that's what you want. :)
Also, my previous solution required a binding for each value in a vector, this
version allows you to bind the leftmost N values of a vector where N <=
vector-length v.
Calculating N could be done at compile-time, but here it's not. I couldn't
get that to work right, so I'd be interested in such a solution.
-d