erlson icon indicating copy to clipboard operation
erlson copied to clipboard

Pattern matching support

Open gleber opened this issue 13 years ago • 5 comments

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?

gleber avatar Jan 13 '12 10:01 gleber

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.

alavrik avatar Jan 13 '12 16:01 alavrik

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.

essen avatar May 10 '12 02:05 essen

Sure! It looks like a useful feature. Just open a pull request and I'll merge it.

alavrik avatar May 12 '12 02:05 alavrik

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.

essen avatar May 15 '12 05:05 essen

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.

alavrik avatar May 16 '12 05:05 alavrik