Macro: CONDLET

Documentation

condlet allows you to locally bind variables based on conditions. syntax: (condlet (<condlet-clause>) forms*) <condlet-clause> ::= (predicate <condlet-binds>*) <condlet-binds> ::= variable | (variable form) semantics: - if one of the predicates yields true, the bindings belonging to it are established within the body - all variables are available in body. If a variable is not bound by a specific condition it's value is nil e.g. (condlet (((= 1 2) (x 1) (y 2)) ((= 1 1) (x 2) (y 1)) (t (x 3) (z 3))) (list x y z)) -> (2 1 nil)

Source

(defmacro condlet (clauses &body body)
  "condlet allows you to locally bind variables based on conditions.
   syntax: (condlet (<condlet-clause>) forms*)
           <condlet-clause> ::= (predicate <condlet-binds>*)
           <condlet-binds> ::= variable | (variable form)
   semantics:
     - if one of the predicates yields true, the bindings belonging to it
       are established within the body
     - all variables are available in body. If a variable is not bound
       by a specific condition it's value is nil
  e.g.
     
       (condlet (((= 1 2) (x 1) (y 2))
	         ((= 1 1) (x 2) (y 1))
         	 (t (x 3) (z 3)))
         (list x y z)) 
     -> (2 1 nil)

"
  (let ((bodfn (gensym))
	(vars (loop for v in (remove-duplicates
			      (mapcar #'car (mappend #'cdr clauses)))
		    collect (cons v (gensym)))))
    `(labels ((,bodfn ,(mapcar #'car vars)
	       ,@body))
      (cond ,@(loop for cl in clauses
		    collect (condlet-clause vars cl bodfn))))))
Source Context