(defpackage :mlet (:use :cl)) (in-package :mlet) (defmacro mlet (bindings &body body) (labels ((aux (bindings new-bindings) (cond ((null bindings) `(let ,(reverse new-bindings) ,@body)) ((typep (car bindings) '(cons (cons (member VALUES)))) (let ((gs (mapcar (lambda (x) (declare (ignore x)) (gensym)) (cdr (caar bindings))))) `(multiple-value-bind ,gs ,(cadr (car bindings)) ,(aux (cdr bindings) (append (mapcar 'list (cdr (caar bindings)) gs) new-bindings))))) (t (let ((g (gensym))) `(let ((,g ,@(if (consp (car bindings)) (cdar bindings) (list 'nil)))) ,(aux (cdr bindings) (cons (list (if (consp (car bindings)) (caar bindings) (car bindings)) g) new-bindings)))))))) (aux bindings nil))) (defmacro mlet* (bindings &body body) `((LAMBDA (&AUX ,@(loop for b in bindings append (cond ((typep b '(cons (cons (member VALUES)))) (let ((g (gensym))) (cons (list g `(multiple-value-list ,@(cdr b))) (loop for i from 0 for v in (cdar b) collect (list v `(NTH ,i ,g)))))) (t (list b))))) ,@body))) #+(or) (mlet (((values x y) (floor 10 3)) (z 200)) (list x y z)) #+(or) (MULTIPLE-VALUE-BIND (G54365 G54366) (FLOOR 10 3) (LET ((G54367 200)) (LET ((Y G54366) (X G54365) (Z G54367)) (LIST X Y Z)))) #+(or) (mlet* (((values x y) (floor 10 3)) (z 200)) (list x y z)) #+(or) ((LAMBDA (&AUX (G54636 (MULTIPLE-VALUE-LIST (FLOOR 10 3))) (X (NTH 0 G54636)) (Y (NTH 1 G54636)) (Z 200)) (LIST X Y Z)))