Dialyzer and parameterized modules

Fernando Benavides <>
Thu Sep 30 19:00:41 CEST 2010


Hi all,
    
I wrote a post in TrapExit OTP/Erlang Forums about this issue.  It says
something like this:

I know that since v2.2.0, dialyzer has support for parameterized
modules, but somehow it's not working for me. 
Lets say that, for some unknown reason (o_O), I want a parameterized
module for atom queues. 
I write this tiny parameterized module then: 
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        -module(atom_queue, [Queue]). 
        
        -export([push/1, pop/0]). 
        
        pop() -> case Queue of 
                   [] -> {undefined, atom_queue:new([])}; 
                   [X|Rest] -> {X, atom_queue:new(Rest)} 
                 end. 
        
        push(X) -> atom_queue:new(lists:reverse([X|Queue])). 
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        
If I run dialyzer on it, no warnings are reported. But it has no specs
and I like to compile my code with warn_missing_spec. The compiler says
that the specs for pop/0 and push/1 are missing. So, I add the specs... 
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        -module(atom_queue, [Queue]). 
        
        -export([push/1, pop/0]). 
        
        -spec pop() -> {undefined | atom(), {?MODULE, [atom()]}}. 
        pop() -> case Queue of 
                   [] -> {undefined, atom_queue:new([])}; 
                   [X|Rest] -> {X, atom_queue:new(Rest)} 
                 end. 
        
        -spec push(atom()) -> {?MODULE, [atom()]}. 
        push(X) -> atom_queue:new(lists:reverse([X|Queue])). 
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Compiler is not complaining anymore, which is great. But when I try to
dialyze the module, I get:
        Contract for function that does not exist: atom_queue:pop/0 
        Contract for function that does not exist: atom_queue:push/1 
        
I change the specs to satisfy dialyzer, like this:
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        -module(atom_queue, [Queue]). 
        
        -export([push/1, pop/0]). 
        
        -spec pop({?MODULE, [atom()]}) -> {undefined | atom(), {?MODULE,
        [atom()]}}. 
        pop() -> case Queue of 
                   [] -> {undefined, atom_queue:new([])}; 
                   [X|Rest] -> {X, atom_queue:new(Rest)} 
                 end. 
        
        -spec push(atom(), {?MODULE, [atom()]}) -> {?MODULE, [atom()]}. 
        push(X) -> atom_queue:new(lists:reverse([X|Queue])). 
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

But, of course, I can't compile that code:
        spec for undefined function atom_queue:pop/1
        spec for undefined function atom_queue:push/2 

So, basically the question is: How can I write a parameterized module
with specs that satisfies both dialyzer and erlc at the same time?


                                                                        
________________________________________________________________________
                                                      Fernando Benavides

                                              



More information about the erlang-questions mailing list