[erlang-questions] Dialyzer vs. Weird List Comprehensions

Fernando Benavides <>
Sun Mar 6 00:32:04 CET 2011


You (and of course Chuck) are right: The warning appears at the line where
all_friends/1 is implemented. What I tried to say was that dialyzer stopped
complaining about that if I removed that line because in every other place I
was calling all_friends with lists that included at least one #buddy with a
non empty list of friends.
So, if I don't want to get that warning, I'll need to avoid using list
comprehensions on empty lists.

Thanks all of you (*) :)

Fernando Benavides

(*) Including Chuck

On Sat, Mar 5, 2011 at 4:12 PM, Kostis Sagonas <> wrote:

> 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 <- []].
>>
>> 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)
>>
>
> Robert Virding has correctly replied that this warning exists because
> dialyzer works at the Core Erlang level where binary comprehensions have
> already been expanded to recursive functions by the Core Erlang translation
> which has one clause for when the list generator is empty and one for the
> cons case.
>
> But I want to point out something more else in your mail:
>
>
>  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.
>>
>
> But what you described is not precise.  It's not only in _one_ of these
> places that this happens, it's in *all* of them (within this module).
> I am sure of this, or there is some other problem in your code.  Chuck
> Norris is even more sure of this. (*)  Disprove him if you dare by sending
> the file that generates this warning!
>
> Cheers,
> Kostis
>
> (*) Fact: Chuck Norris can find and understand all bugs in an Erlang
> program without seeing the code.
>   (for more facts see http://www.chucknorrisfacts.com/)
>



-- 
*Fernando Benavides <http://google.com/profiles/greenmellon>*


More information about the erlang-questions mailing list