[erlang-questions] Dialyzer vs. Weird List Comprehensions

Robert Virding <>
Sat Mar 5 00:23:12 CET 2011


One guess is that might depend on the fact that dialyzer works on Core erlang, an internal compiler format, and at that stage list/binary comprehensions have already been expanded into local recursive functions. These comprehension functions will contain a clause which against the head of a list. Dialyzer will then detect that the comprehension function is only called with a [] and then warn that the pattern in this clause can never match.

But this is just a guess.

Robert

-- 
Robert Virding, Erlang Solutions Ltd.

----- "Fernando Benavides" <> wrote:

> Hi, I think this question is mostly for the man of the moment, Kostis
> Sagonas ;). But, if everybody else had run into this kind of things
> before, your help is appreciated.
> I have a quite complex module and at one point there is a function
> that
> uses list comprehensions over one of its parameters. That parameter,
> may
> eventually be an empty list (a hardcoded empty list - i.e. when know
> that in that particular case it'll be an empty list at compile time).
> So, when I try to run dialyzer on my module, it prints a warning
> about
> that when in my opinion, it shouldn't.
> To make things easier to understand, I've isolated the problem in
> this
> rather useless module:
> 
>         -module(listcomp).
>         -export([sample/0]).
>         -spec sample() -> [].
>         sample() -> [L || L <- []].
> 
> Now, you can compile and run it:
> 
>         1> c(listcomp).
>         {ok,listcomp}
>         2> listcomp:sample().
>         []
> 
> It works fine, but if you try to dialyze it...
> 
>         $ dialyzer ebin/listcomp.beam
>           [...]
>         listcomp.erl:4: The pattern [L | _] can never match the type
> []
>          done in 0m0.31s
>         done (warnings were emitted)
> 
> 
> First thought is "why are you doing a list comprehension on an empty
> list anyway?". But, for instance, the actual line in my module is
> something like this:
> 
>         all_friends(Buddies) -> [db:get_buddy(FN) ||
> #buddy{friend_names
>         = FNs} <- Buddies, FN <- FNs].
> 
> 
> And it's called from a lot of places... one of those looks like
> this...
> 
>         all_friends([#buddy{name = "Jim (from 28 days later...)",
> ...},
>         #buddy{name = "Chuck Norris", ...}])
> 
> 
> ...and you know... neither of those folks have any friends, so
> dialyzer
> complains.
> 
> What do you think? Is it a bug? Should I modify my code not to use
> list
> comprehensions on that case?
> 
> Cheers!!
> 
>                                                                       
>  
> ________________________________________________________________________
>                                                       Fernando
> Benavides
> 
>                                              
> 


More information about the erlang-questions mailing list