Hi,
I just hacked the following macro:
(defmacro multiple-value-case (&body clauses) (when clauses (destructuring-bind (first &rest rest) clauses (cond ((member (first first) '(t otherwise)) (when clauses (warn "Dead code: ~S." clauses)) `(progn ,@(rest first))) (t (destructuring-bind ((&rest lambda-list) expression (guard) &rest body) first `(multiple-value-bind ,lambda-list ,expression (if ,guard (progn ,@body) (multiple-value-case ,@rest)))))))))
Did anybody see anything similar before? Any suggestions for improvement?
Thanks, Pascal
From: Pascal Costanza pc@p-cos.net Date: Fri, 26 Nov 2010 14:36:57 +0100
(defmacro multiple-value-case (&body clauses) (when clauses (destructuring-bind (first &rest rest) clauses (cond ((member (first first) '(t otherwise)) (when clauses (warn "Dead code: ~S." clauses))
Surely:
(when rest (warn "Dead code: ~S." rest))
-n
`(progn ,@(rest first))) (t (destructuring-bind ((&rest lambda-list) expression (guard) &rest body) first `(multiple-value-bind ,lambda-list ,expression (if ,guard (progn ,@body) (multiple-value-case ,@rest)))))))))
On Fri, 26 Nov 2010 14:36:57 +0100, Pascal Costanza said:
Hi,
I just hacked the following macro:
(defmacro multiple-value-case (&body clauses) (when clauses (destructuring-bind (first &rest rest) clauses (cond ((member (first first) '(t otherwise)) (when clauses (warn "Dead code: ~S." clauses)) `(progn ,@(rest first))) (t (destructuring-bind ((&rest lambda-list) expression (guard) &rest body) first `(multiple-value-bind ,lambda-list ,expression (if ,guard (progn ,@body) (multiple-value-case ,@rest)))))))))
Did anybody see anything similar before? Any suggestions for improvement?
I am confused about why guard has parens around it. It might be better to group the guard and the body like cond does, i.e.
(destructuring-bind ((&rest lambda-list) expression (guard &rest body)) first
Also the nesting of the multiple-value-binds in the expansion leads to unexpected lexical scoping. Maybe if you call it multiple-value-cond* ...
On 26 November 2010 08:36, Pascal Costanza pc@p-cos.net wrote:
I just hacked the following macro:
(defmacro multiple-value-case (&body clauses) (when clauses (destructuring-bind (first &rest rest) clauses (cond ((member (first first) '(t otherwise)) (when clauses (warn "Dead code: ~S." clauses)) `(progn ,@(rest first))) (t (destructuring-bind ((&rest lambda-list) expression (guard) &rest body) first `(multiple-value-bind ,lambda-list ,expression (if ,guard (progn ,@body) (multiple-value-case ,@rest)))))))))
Your macro is leaking bindings like a sieve. The correct thing to do is to destructure into gensyms, then rebind in the body (that can have declarations of ignores).
Did anybody see anything similar before? Any suggestions for improvement?
You could use fare-matcher which will do it all for you. Won't expand to super-efficient code, unless your compiler is good at optimizing linear lambdas away.
[ François-René ÐVB Rideau | Reflection&Cybernethics | http://fare.tunes.org ] Anyone who says he can see through women is missing a lot. — Groucho Marx