[erlang-questions] Trouble with init/1 spec

Jay Nelson <>
Wed Mar 24 19:19:43 CET 2010

On Mar 24, 2010, at 9:40 AM, Kostis Sagonas wrote:
> For example, I tried the following (a simplified version of your  
> code):
> ---------------------------------------------------------------
> -module(jay).
> -export([init/1]).
> -record(twfsm_state, {server = "abc" :: string(),
>                       port = 42 :: integer()}).
> -spec init(list()) -> {ok, #twfsm_state{}}.
> init([Server, Port]) ->
>     {ok, #twfsm_state{server=Server, port=Port}}.
> ---------------------------------------------------------------
> I really want to understand this.  What exactly is that you claim  
> you cannot really do without getting a dialyzer warning?
> Kostis

I had another mistake in one of the other fields in the record that  
caused the problem (but other errors led me to my arguments issue).   
I had declared:

-record(twfsm_state, {
                server :: string(),
                port :: pos_integer(),
                conn_attempts = 0 :: pos_integer()

jay.erl:20: The specification for jay:init/1 states that the function  
might also return {'ok',{'twfsm_state','undefined' | string 
(),'undefined' | pos_integer(),pos_integer(),binary()}} but the  
inferred return is none()
jay.erl:22: Function init/1 has no local return
jay.erl:23: Record construction #twfsm_state{server::any(),port::any 
(),conn_attempts::0} violates the declared type for #twfsm_state{}

Changing conn_attempts to non_neg_integer() solves the problem that  
my initial value is invalid for the type.

What would have helped is if the record construction error singled  
out only the fields that violated the declared datatypes after the  
entry 'jay.erl:23', maybe as a list similar to  
error_logger:error_report might present, since I actually had 15 or  
so fields.

For example:

jay.erl:23: Record construction #twfsm_state{server::any(),port::any 
(),conn_attempts::0} violates the declared type for #twfsm_state{}

jay.erl:23: The following fields are incorrect:
conn_attempts::0 => pos_integer()

Although, I still would have thought there was a type failure.  In  
your example, you set the values of the record to values of type any 
() even though they were declared to be of type string() and integer 
().  Why is that acceptable?  In my error printout it shows dialyzer  
interpreting the fields as type any().


More information about the erlang-questions mailing list