-
Notifications
You must be signed in to change notification settings - Fork 719
Description
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)