I finally finished implementing pattern matching!
I just looked to see when I last updated this blog, and holy crap, it’s been half a year! I tell ya, this had better be one nice feature.
For what it’s worth, I think it is. The pattern matching is recursive, meaning you can break components down as far as you want:
case myWhatever of Something(List(BlahBlah(5, a), _)) -> ...
That will match if
myWhatever is a
Something whose only argument is a
List whose first element is a
BlahBlah with two arguments, the first being an int
5 and the second being anything, and that thing is now bound to the variable
That took a bit of work, though it only gets me to parity with other pattern matching languages. What’s neat about Haskell is that the remaining type — that is, the next line in the
case list — will take all of that into account. Taking a simpler example, this would fail to compile:
case coinFlips of List(Heads, List(Tails, _)): ... List(Heads, List(Tails, _)): ... _: ...
because the second line is trying to match against a pattern that’s already been matched. And likewise, without that last
_ -> ... line, the statement would fail to compile because some
coinFlips types have not been accounted for (namely,
List(Heads, Empty | List(Heads, _) | List(Tails, _)).
There’s still room for improvements:
- you can’t match against an alias or disjunctive type (ie, you can’t match for
Boolean, you have to look for
- the “remaining type” tends to be pretty exploded out; instead of
List(Heads, Empty | List(Heads, _)it might say
List(Heads, Empty) | List(Heads, List(Heads, _). After a few of these exploded forms chain together, it can get pretty hairy
- There’s no tracking of values for what I call “large domain values,” such as ints (as opposed to small domain values, such as
True | False. For instance, if you match an int against
5, nothing prevents you from matching against
- There’s no mechanism for variable arity destructors, which is why the
List(...)pattern above had to be desctructed node by node, instead of just as
List(Heads, Tails, _)
I may pick off one or two of these soonish, but frankly I’m ready to put pattern matching aside for a bit. It’s taken longer than I’d have liked, and it’s time to move on to some more features.
I think the next thing I’m going to do is exception handling, about which I have some neat ideas. After that, I’m going to fill in the built-in types (which currently only include ints), and for strings I intend to include string interpolation. After that, I’m going to do some I/O work of some sort. And at that point, I think I’ll be ready to start writing some real code in Effes, at lon