[erlang-questions] Dialyzer vs. Weird List Comprehensions
Fernando Benavides
fernando.benavides@REDACTED
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 <kostis@REDACTED> 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