Re:The Array Cast – A podcast about the array programming la...
by kazinator on Thursday May 20, 2021 @05:45PM
(#27227763)
The original requirements should be addressed. The thing being matched is not just select, but actually any one of a set of symbols that appear in K.
We can stick that data into the pattern matching syntax using the or operator:
3> (rewrite-case x '(foo bar * select * fox where * bravo)
((@(or select distinct partition from where
group having order limit) * . @rest) ^(,(car x) _ . ,rest))
(@else else))
(foo bar * select _ fox where _ bravo)
Or put it into a variable: 4> (defvarl K '(select distinct partition from where group having order limit))
K
5> (rewrite-case x '(foo bar * select * fox where * bravo)
((@(member @sym K) * . @rest) ^(,sym _ . ,rest))
(@else else))
(foo bar * select _ fox where _ bravo)
"If an object sym which is a member of K is followed by * and some remaining material, replace that by sym, underscore and that remaining material."Hash table:
6> (set K (hash-list '(select distinct partition from where group having order limit)))
#H(() (select select) (where where) (limit limit) (order order)
(having having) (distinct distinct) (partition partition) (group group)
(from from))
7> (rewrite-case x '(foo bar * select * fox where * bravo)
((@[K @sym] * . @rest) ^(,sym _ . ,rest))
(@else else))
(foo bar * select _ fox where _ bravo)
This code golfs moderately well: https://news.ycombinator.com/item?id=27227276
E.g. a function early-peephole looks for one particular four instruction pattern (six items, when the labels are included). Rewriting it to a different form helps it disappear later on.
This is much more general and powerful than a hack which just looks at successive pairs for an ad-hoc match. rewrite-case can have multiple clauses, of different lengths, and arbitrary matching complexity.