Skip to content

Special Patterns

Masataro Asai edited this page Jul 14, 2016 · 10 revisions

This section contains patterns that has specific roles in itself.

Place Pattern

Syntax
place variable &optional eager

Just the same as using variable as a variable pattern, except the variable is accessed by symbol-macrolet instead of let. This allows the use of setf to modify the matched object, and also delay the evaluation of the accessor.

If eager variable is provided, then it is bound by let. (Useful when the duplicated calls to the accessor can be a bottleneck.)

Example:

(defvar *x* (list 0 1))
(match *x*
  ((list (place x) y)
   (setf x :success)
   (setf y :fail)))

(print *x*)
;; --> (:SUCCESS 1)

Bind Pattern

Syntax
<> pattern value &optional var

The current matching value is bound to var. The result of evaluating value using var is then matched against pattern. var is optional and can be omitted when value is a constant and does not need the current matching value.

This is important when you write a defpattern that has a default value. Consider writing a derived pattern that matches against both a symbol string and a form (string *). It has a subpattern length, which should be bound to a symbol * even when the input is string. With <> pattern, it can be implemented as below.

(defpattern string-type-specifier (length)
   `(or (list 'string ,length)
        (and 'string (<> ,length '*))))

(match 'string
  ((string-type-specifier length)
   length))
; '*

(match '(string 3)
  ((string-type-specifier length)
   length))
; 3

Access Pattern

Just want to access an element? It’s time to use access pattern:

Syntax
access accessor subpattern
accessor
a function designator.

No check is conducted on the object. The value of funcall ing the accessor with the current object is matched against subpattern.

Example:

(match '((1 2 (3 4)) 5 (6))
  ((access #'flatten (list* _ _ 3 _))))
You can’t perform that action at this time.