Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pattern matching support #3

Open
gleber opened this issue Jan 13, 2012 · 5 comments
Open

Pattern matching support #3

gleber opened this issue Jan 13, 2012 · 5 comments
Labels

Comments

@gleber
Copy link

gleber commented Jan 13, 2012

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?

@alavrik
Copy link
Owner

alavrik commented Jan 13, 2012

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.

@essen
Copy link

essen commented May 10, 2012

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.

@alavrik
Copy link
Owner

alavrik commented May 12, 2012

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

@essen
Copy link

essen commented May 15, 2012

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.

@alavrik
Copy link
Owner

alavrik commented May 16, 2012

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants