Chapter 8 - recursive expansion of abbreviated patterns
homedirectory opened this issue · comments
Description
8.3 Associativity and Commutativity
The following pattern matching abbreviations are defined in such a way that causes a recursive expansion:
;; Define n and m as numbers; s as a non-number:
(pat-match-abbrev 'n '(?is n numberp))
(pat-match-abbrev 'm '(?is m numberp))
(pat-match-abbrev 's '(?is s not-numberp))
For example, we can see here that the 2nd n
got recursively expanded (its binding is the first item in the resulting list).
> (pat-match '(n n) '(5 5))
(((?IS (?IS N NUMBERP) NUMBERP) . 5) ((?IS N NUMBERP) . 5))
This happens because the first thing pat-match
does is expand the received pattern. At the same time it might be called recursively (e.g., by single-matcher
), thus expanding the rest
of an already expanded pattern...
In the above example (n n)
will be first expanded to ((?is n numberp) (?is n numberp))
, the car
of which will get processed by single-matcher
, while the rest
will be recursively processed by pat-match
, which will expand (?is n numberp)
into (?is (?is n numberp) numberp)
.
Improvement
I've managed to avoid this by eliminating the recursive relationship and using ?n
instead:
(pat-match-abbrev '?n '(?is n numberp))
Consequently, affected simplification rules had to be modified to use ?n
on the left-hand side but just n
on the right hand-side. For example:
(?s * ?n = n * s)
(?n * (?m * x) = (n * m) * x)