PCOND supports Lisp predicates, regular expressions, and unification expressions. (The "P" in the name is for pattern matching.)
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.