erlson
erlson copied to clipboard
Pattern matching support
I was wondering if it is possible to implement the simple pattern matching cases like:
case X of
#{a = A, b = B} -> true
#{a = A, b = 42, c = C} -> false
end
introducing some artificial variables at compile time:
_TMP36 = X.a,
_TMP95 = X.b,
_TMP28 = X.c,
case {_TMP36, _TMP95, _TMP28} of
{A, B, _} -> true
{A, 42, C} -> false
end
This would be much more complicated if we want to implement pattern matching for function clauses and more complex cases. But even such implementation would be a small step forward.
Anton, what's your opinion on this?
Gleb, I like the idea of generalizing Erlson syntax to support pattern-matching. I was thinking about ways to achieve it, but couldn't find a simple enough general-purpose solution.
Even for the case you are suggesting, it is more complicated than that. For instance, as a fist step, you need to assign expression (X)
to a temporary variable. Now, what if the result of X
contains nested Erlson dictionaries and you want to match against their elements?
Also, suppose there's no element a
in X
. It would be reasonable to assume that all case clauses that mention a
should not match. However, with your transformation you will get an Erlson exception before you even get to the case
.
More importantly, by transforming case X of
to case {...} of
you are basically doing local type inference, and if you had more case clauses covering different data types, you wouldn't be able to do this. Instead, I would probably expand each clause of an Erlson record to a chain of nested clauses, each probing one Erlson element at a time.
Even if we don't consider function clauses, there are guard expressions and other pattern matching constructs (e.g. #{...} = X,
) that need to be covered.
It is likely that all these things can be figured out and I don't mean to discourage you from doing this. It would be an interesting project, but it requires more time than I personally would be able to spend on it.
Would you consider at least allowing pattern matching like the following? (Just a quick access to many variables in the dictionary)
#{a=A, b=B, c=C} = Dict,
I can send a patch if you wish.
Sure! It looks like a useful feature. Just open a pull request and I'll merge it.
Alright I will. However, considering how peculiar the project is, could you give me some pointers as to what I need to modify in order to add this? Is there changes to be made to the lexer/parser or should I be fine just matching and replacing in the parse transform?
Thanks.
Implementing it as a parse transform should be fairly straightforward. This is the clause in erlson_pt.erl
you are interested in:
expr({match,LINE,P,E_0}, S) ->
{match,LINE,?pattern(P),?expr(E_0)};
I would't bother adding an in-place parse transform to erl_parse_shell.yrl
files as this specific feature doesn't seem to be very useful in interactive shell. Moreover, it would be a fairly intrusive change which goes against Erlson approach. I try to keep grammar changes minimal to make them easily portable to future Erlang versions.