Extending Pattern Matching in Racket
Racket amazes me every time. I recently wanted to have a pattern to match a deep nesting structure, how difficult that could be?
First, pattern matching in Racket:
https://gist.github.com/ruliana/0eea54a4e3a242ad2da3f4eef1c8ba4c
Above we declare a variable “some-list” with “b”, “a”, “c”. Then we match it with two possible lists, one with “a” in the first position, other with “b” in the first position. The right-hand side the expressions are executed if the left-hand side matches. That’s pretty straightforward if you ask me.
You can check the Racket documentation for a complete reference of possible patterns.
One of the nice parts of pattern matching is that it can be used to destructure things in a variable declaration like this:
https://gist.github.com/ruliana/f2aa2c4847b329363446aaf00eabf3b3
Here, “(list xs … x)” is a pattern and “some-list” is being destructured. The “xs” is a new variable with the first elements of the list and “x” is a new variable with the last element.
Finally, using the example of John Clements in an old StackOverflow post, I want to create an “aba” pattern, meaning it matches a list where the first and third elements are the same:
https://gist.github.com/ruliana/8102932aa7aea36094f25e44183b14f1
Here, “define-match-expander” defines a new custom pattern named “aba”. The “(syntax-rules () …” is just boilerplate code for what we are interested, ignore it for now. The important part is “(aba a b) (list a b a)”; in a pattern match “(aba a b)” is replaced by “(list a b a)”. Et voilà! That can be used as a new pattern matching or for destructure variables.