[erlang-questions] List comprehension filter expressions not throwing exceptions

Kostis Sagonas <>
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