[erlang-questions] This clause cannot match because....

Richard Carlsson carlsson.richard@REDACTED
Tue May 9 11:18:49 CEST 2017


I had to dig a bit to see what happens. The report in this case (the second
example) is generated by the pattern matching compilation in the
v3_kernel.erl module, and it only does so when it happens to see that a
branch will never be taken. It doesn't try more systematically to figure
out which clauses would be covered by earlier ones. (There are some other
cases where the compiler can detect earlier that clauses are not reachable,
when the input is known or partly known, but this is not such a case.)

When the pattern matching compilation comes to the point where it knows it
has either ...B] or ...b], it checks whether there is a [] (empty list)
after the position of B, and in that case it matches B and is happy.
Otherwise it goes on to look at whether it has a 'b', and in that case
whether that 'b' is followed by the empty list. But it forgets that it has
checked for [] in that position already, and no warning is generated.


        /Richard

2017-05-08 14:54 GMT+02:00 Stefan Hellkvist <hellkvist@REDACTED>:

> Hi all,
>
> I was just struck by a bug in my code due to wrong ordering of clauses.
> Given a function f/1 which could be simplified to something like this:
>
> f([a, B]) ->
>     B;
> f([a, b]) ->
>     will_never_happen.
>
> The problem is that the clause f([a, b]) is never taken simply because it
> is fully covered by the first clause which matches all values for the
> second element in the list. If I had put the second clause before the more
> general clause it would have worked the way I thought it should.
>
> I'm curious though. Why did the compiler not spot the problem in the code
> for f/1 when it can obviously spot the problem in a, to me at least,
> similar function f/2 seen below?:
>
> f(a, B) ->
>     B;
> f(a, b) ->
>     will_never_happen.
>
> In this example, (f/2), I get a compilation error with a very good and
> detailed description of what the problem is, but in the first case (f/1)
> the compiler does not see the problem (or cannot?) with the covering
> clause.
>
> Is this some edge case where the compiler has just stopped caring and I
> must use dialyser to spot the problem at an earlier stage than at runtime?
>
> Stefan
>
>
> p.s. funny thing is that if I use a tuple instead of a list to create f/1
> in the same way the compiler is once again able to spot the problem, but
> not with a list as argument.
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20170509/424ca80a/attachment.htm>


More information about the erlang-questions mailing list