[erlang-questions] eep: multiple patterns
Andras Georgy Bekes
bekesa@REDACTED
Wed May 14 16:20:19 CEST 2008
Hi,
After we've discussed the topic (mainly in the "erlang *****" thread),
I've made the eep-document. I send it to the list for further
discussion.
I haven't received any comments on the proposed pattern-match-test
construct, which is sad as I am not satisfied with what I'm about to
recommend.
There are 3 possibilities:
1, Only _ (underbar) names are allowed.
+ sounds logical, because no variables will be bound anyways.
- Patterns with syntactic restrictions is a new concept in Erlang
2, Only _ and names beginning with _ are allowed.
+ giving meaningful names instead of _-s is a documentation of the code
+ multiple occurences of the same variable in a pattern are meaningful
and useful
- Later use of a variables that occured in a pattern-match-test
is confusing, because they are totally independent
- Patterns with syntactic restrictions is a new concept in Erlang
3, No restrictions.
- Variables not beginning with _ are bad, because
* not using it later results in compiler warning
* using it later is confusing (see above)
I don't really like any of the above, but I still think that a
pattern-match-test operator is very useful, so I'm eager to listen to
every constructive opinion.
Georgy
-------------- next part --------------
EEP: XX
Title: Multiple patterns
Version: XX
Last-Modified: XX
Author: András Georgy Békés <Andras.Gyorgy.Bekes@REDACTED>
Status: Draft
Type: Standards Track
Erlang-Version: R12B-?
Content-Type: text/plain
Created: 05-May-2008
Post-History: 14-May-2008
Abstract
This EEP describes the syntax and semantics of multiple patterns
for function clauses and case, receive, try-catch expressions.
It also describes the pattern-match-test expression.
Rationale
It is rather common to check the value of an expression with a
case expression and do the same actions in some of the cases.
Example:
case Expression of
Pattern1 ->
%% think lots of code here
Pattern2 ->
%% think the same piece of code as above here
Pattern3 ->
%% something else here
end
In order to avoid duplicated code, the programmer might extract
the duplicated body into a separate function, or might separate the
classification of results from the execution of actions.
Example:
Type = case Expression of
Pattern1 -> {type1,Values...};
Pattern2 -> {type1,Values...};
Pattern3 -> {type2,Values...}
end,
case Type of
{type1,Patterns...} ->
%% think lots of code here
{type2,Patterns...} ->
%% something else here
end
Both the solutions are lengthy. According to a discussion on the
mailing list erlang-questions [1], [2], the ultimate solution would
be to introduce union- and negated patterns, but that would have
unacceptable consequences (in performance).
The proposed multiple-patterns together with pattern-match-test
solves all the (practical) problems the union- and negated patterns
could be used for.
Syntax
In function heads:
functionname(Pattern1) when GuardSequence1 |
functionname(Pattern2) when GuardSequence2 ->
%% function body to be executed in both cases
functionname(Pattern3) when GuardSequence3 ->
%% other function clauses
In case expressions:
case Expression of
Pattern1 when GuardSequence1 |
Pattern2 when GuardSequence2 ->
%% think the same piece of code as above here
Pattern3 ->
%% something else here
end
receive and try-catch expressions are analogous to the case
expression.
Semantics:
A function head or case, receive, try-catch expression with
multiple patterns means that the body is selected whenever at
least one of the patterns match. The order in which the patterns
are checked is obviously irrelevant. Variables not bound in each
of the cases should be considered unsafe, i.e. cannot be used in
the body or after the case, receive or try-catch expression.
Note that this behaviour could be easily implemented with a parse
transformation: the body could be simply copied for each of the
patterns. However, the syntax would be very ugly, because it
would have to use syntax that the current parser accepts.
Pattern-match-test Operator
The pattern-match test operator is an operator-like construct.
It is not an operator because one of its arguments is not an
expression but a pattern. The operator tests whether its expression
argument matches its pattern argument, and returns true or false.
Syntax
PATTERN ~= Expression
Semantics
The operator first evaluates Expression, then tests if it matches
PATTERN. The result is true/false. No variables are bound. The
operator should be allowed in guards.
Note that this behaviour could be easily implemented with a parse
transformation, by replacing each pattern-match-test with:
case Expression of
PATTERN ->
true;
_ ->
false
end
but this can not be used in guards, and the most important use
of the operator would be to extend pattern matching with negated
patterns as in the following example pattern:
PATTERN1 when not (PATTERN2 ~= Variable_bound_by_PATTERN1)
Compatibility
Currently there is neither | nor ~= operator in Erlang, therefore
legacy code works as before.
References
[1] Discussion on union- and negated patterns
http://www.erlang.org/pipermail/erlang-questions/2008-March/033718.html
[2] Discussion on union- and negated patterns
http://www.erlang.org/pipermail/erlang-questions/2008-March/033755.html
Copyright
This document has been placed in the public domain.
Local Variables:
mode: indented-text
indent-tabs-mode: nil
sentence-end-double-space: t
fill-column: 70
coding: utf-8
End:
More information about the erlang-questions
mailing list