[erlang-questions] eep: multiple patterns

Andras Georgy Bekes <>
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 <>
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