[erlang-questions] Dialyzer bug or some problem with my code

Anthony Molinaro <>
Tue Mar 22 04:28:50 CET 2011

On Tue, Mar 22, 2011 at 02:26:46AM +0200, Kostis Sagonas wrote:
> Anthony Molinaro wrote:
> >Hi,
> >
> >  Not sure if this is a bug or not, but the attached file exhibits the
> >following.
> >
> >% erlc tmp.erl
> >% erl -eval 'tmp:test(), init:stop()' -noshell
> >  All 2 tests passed.
> >% dialyzer -Wno_opaque tmp.erl
> >  Checking whether the PLT /Users/molinaro/.dialyzer_plt is up-to-date... yes
> >  Proceeding with analysis...
> >tmp.erl:19: Function key_in_dict/2 has no local return
> >Unknown functions:
> >  eunit:test/1
> > done in 0m0.63s
> >done (warnings were emitted)
> >
> >Using R14B02.  As far as I can tell the key_in_dict function always returns
> >so I'm not sure why it would have no local return.  I can always work around
> >with -Wno_return but I already don't like the fact that I have to work around
> >dict being an opaque type with -Wno_opaque (is that ever going to get fixed?).
> You've put yourself in a corner and now you are wondering why you
> are there...
> The option -Wno_opaque does not mean what you think it means: it
> simply shuts off all dialyzer *warnings* about opacity violations in
> your code. But it does not make dialyzer change its default
> behavior, which is to consider all opacity violations as failures.
> Without this option, dialyzer complains that:
> tmp.erl:11: The call tmp:key_in_dict(A::any(),Dict::tuple()) does
> not have an opaque term of type dict() as 2nd argument
> tmp.erl:19: Function key_in_dict/2 has no local return
> tmp.erl:20: The call
> dict:is_key(Key::maybe_improper_list(),Dict::tuple()) does not have
> an opaque term of type dict() as 2nd argument
> and it's exactly the warning in line 20 which makes dialyzer think
> that you are doing something wrong there.  For better or worse,
> dict() is defined as an opaque data type, in the Erlang
> documentation also, which means that you should not really inspect
> its structure with type tests and element/1 like you do in your
> code:

Okay, that's unfortunate.  I realize I'm peeking behind the curtain here but
what other choice do I have without any sort of dict:is_dict/1 function.

> In your case you can cheat a bit and "have your cake and eat it
> too", if you are willing to come to terms that the "let it fail"
> philosophy is actually a good design principle and your code should
> not just return false if you happen to pass something unexpected to
> the second argument of in_thing/2. You can then write your code as:
> in_thing (A, B) ->
>   case B of
>     List when is_list (B) ->  % IMO: this should read is_list(List) here
>       key_in_list (A, List);
>     Dict ->
>       key_in_dict (A, Dict)
>   end.

The problem here, is this was just a simplified example in the real code I
do do something in the third case, so reordering in this way won't quite
help me.  I guess I can just -Wno_opaque -Wno_return for the moment :(

Maybe the OTP team can add an is_dict/1 at some point.  Seems like most of
the other opaque types have a function to determine if a random term is
of that type.  The code would be slightly more convoluted as it would
be nested conditionals like

in_thing (A, B) ->
  case dict:is_dict (B) of
    true ->
      key_in_dict (A, B);
    false ->
      case B of
        List when is_list (List) ->
          key_in_list (A, B);
        _ ->

Although not the cleanest at least it should dialyze correctly, and if I
wanted to support additional types (for instance maybe I want to allow a
set of some sort, I could add it using the is_set/1 function call).

Looking through the standard data structures I see that


all exists, but these are missing


Is there any reason these haven't been added to OTP yet?  Something about
these last three structures which have kept them from getting a function
to determine if a term is of the given type?  (they all seem to be a
dictionary like structure, so maybe something about dict structures means
we can't have an is_dict/1?).

Just wondering,


Anthony Molinaro                           <>

More information about the erlang-questions mailing list