[erlang-questions] List comprehension filter expressions not throwing exceptions
Kostis Sagonas
kostis@REDACTED
Thu Sep 30 11:55:56 CEST 2010
Sam Bobroff wrote:
> Hi all,
>
> I've discovered (after some rather painful debugging) that badrecord
> exceptions (and others, actually) are sometimes silently converted to
> false when they're generated inside a list comprehension filter
> expression (as if they were a guard?).
>
> I couldn't find any reference to this behaviour in the manual, so
> perhaps it's a bug or perhaps there needs to be a note in the manual. It
> certainly surprised me.
>
> Here's some code to reproduce the behaviour:
>
> -module(lc).
> -export([a/0, b/0]).
> -record(rec, {x}).
>
> a() ->
> [E || E <- [1], E#rec.x =:= 1].
>
> b() ->
> [E || E <- [1], check_element(E)].
>
> check_element(E) ->
> E#rec.x =:= 1.
>
> Tested on R13B04, R14A or R14B, I get:
>
> $ erl
> Erlang R14A (erts-5.8) [source] [smp:2:2] [rq:2] [async-threads:0]
> [hipe] [kernel-poll:false]
>
> Eshell V5.8 (abort with ^G)
> 1> c(lc).
> {ok,lc}
> 2> lc:a().
> []
> 3> lc:b().
> ** exception error: {badrecord,rec}
> in function lc:check_element/1
> in call from lc:'-b/0-lc$^0/1-0-'/1
> 4>
>
> Where I would expect both a() and b() to crash with badrecord. As the
> code shows, executing the same expression wrapped in a function call
> *does* cause the exception to be raised, so it's not as simple as all
> exceptions being converted.
Your expectations are wrong. It's not the function call that is to blame
here. The problem is that your b+check_element code is not equivalent to
the code of the a() function. The equivalent code is:
b() ->
[E || E <- [1], check_element(E)].
check_element(E) when E#rec.x =:= 1 ->
true;
check_element(_) ->
false.
which does not raise an exception either.
Kostis
More information about the erlang-questions
mailing list