PCOND is superseded by optima. Please use optima instead of PCOND. optima is better designed and well-maintained, when PCOND isn't. The syntax is not compatible, but optima is arguably better designed, and migration is easy.
Author: Eric Normand
It binds variables to the values it matches to. Those bindings are available in the body of the conditional.
It currently has three pattern types it matches:
ordinary LISP predicates
(:re "xy(z+)" str (zs)) ;; matches the regular expression to ;; the value of STR. If it matches, ;; ZS is bound to the matching group.
(:pat (?x . ?rest) ls) ;; matches the pattern against the value ;; of LS. Binds the variables ?X and ;; ?REST to the results of the ;; unification.
Another great feature is that you can "nest" the conditionals.
* (pcond:pcond ((and (:pat (?x . ?xs) '(a b)) (:re "xyz" "xyz")) 'match)) MATCH
* (pcond:pcond ((and (:re "ab(\\d*)" "ab12" ((#'parse-integer num))) (some #'(lambda (x) (and (:pat (?x ?y . ?rest) x) (= ?y num))) '((a 1) (b 2 h) (c 12 j) (f 12)))) ?x)) C
(defun my-map (fn ls) (pcond:pcond ((null ls) nil) ((:pat (?x . ?xs) ls) (cons (funcall fn ?x) (my-map fn ?xs)))))
In addition, the conditional is extensible. You can add your own pattern types to match to.