[erlang-questions] eep: multiple patterns

Richard A. O'Keefe <>
Thu May 15 03:27:55 CEST 2008

I feel that this proposal is a step in the wrong direction,
and has "hack" written all over it.

Let's start with the pattern-match operator,

	pattern ~= expression

I already feel slightly queasy at the fact that pattern matching
is associated with guards everywhere EXCEPT pattern = expression;
adding another construction that will work some but only some of
the time does not appeal to me.  Right now, I can do

	1 = f()

but I cannot do

	(X when X > 1) = f()

Right now, any instance of
	case E1 of P1 -> B1 end		% just one clause!
can be rewritten as
	(P1 = E1, B1).
Why not extend this to allow
	case E1 of P1 when G1 -> B1 end
to be written as
	((P1 when G1) = E1, B1)

I'm not pushing _hard_ for this, you understand, just
noting that there is a nasty and apparently unmotivated
gap in the language, and suggesting that something
should be done about it.  Abstract patterns are, of
course, a far better solution to the same issue.

Of course the same idea can be extended to ~=, and if ~=
were to be extended, it should be.

The draft EEP notes that the ~= construction adds no
real power (and, if we consider macros, no extra power
at all) in ordinary expressions.  It is ONLY useful in
guards.  But WHY is it useful?

~= is only useful because = is not allowed in guards.

Between a pattern match test that doesn't bind any
variables and a pattern match test that only binds
variables that happen not to be used anywhere else
there is no real difference.  ~= is a special case of
= .  So if we are willing to consider ~= in guards,
why not consider = in guards?

Indeed, why not?  If I can write

	f(L) when hd(L) > 0, hd(L) < 10 ->

why can't I write

	f(L) when N = hd(L), N > 0, N < 10 ->

In the past I have strongly defended the distinction
between guards and expressions, and I have not changed
my mind.  But allowing = in guards does not destroy any
of the properties of guards that have ever concerned me.

So instead of adding a new "crippled-bind" called ~=,
I suggest that it would be better to allow
Pattern = Expression as a guard.

What about the intended uses of ~= where the fact that
it does not bind variables is important?  Why then,
just restrict the corresponding = to not bind variables.
{foo,_,27} = hd(X) would have the same effect in a guard
as {foo,_,27} ~= hd(X) would have, so if we allowed =,
there would be no point in having ~= as well, while if
we had ~= we would still be left lamenting the
inexplicable prohibition on =.

Do I need to mention that the similarity between = and
~= would lead to errors when one was used but the other
intended?  No, I thought not.  ~= is something we are
better off without.  But its use in guards _is_ something
we could do with, only the existing = would be far better.

That's enough for one message, I think.

Maybe not.

I don't like vague suggestions that
"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."
I want to see *actual cases*.

Oh, and did I point out that abstract patterns can solve the
"multiple patterns" problem neatly and clearly?

More information about the erlang-questions mailing list