m2ym/optima

Optional pattern

dmitrys99 opened this issue · 2 comments

Is there a way to implement optional items in pattern, like "?" operation in regexp?
So, for example (list a b (? c)) will allow skip part 'c'?

m2ym commented

No, but you can use or pattern instead like (or (list a b) (list a b c)). It is possible to implement optional pattern as pattern expansion.

Without explicit support, you will end up something like this.

(defpattern list? (&rest args)
  (process-list? args))

(defun process-list? (args)
  (let* ((pos (position-if (lambda (x) (and (consp x) (eq (car x) '?))) args))
          (? (elt pos args)) (content (second ?)))
     `(or ,(process-list? (subst content ? args))
            ,(process-list? (remove ? args)))))

Unfortunately however, this does not provide a general implementation of ?. You always have to implement ?-compatible version of whatever pattern you use, e.g., when you try to use ? for vector, you should implement and use vector?. Fundamentally this has the same problem as macro expansion (expansion cannot see the outer construct).