[erlang-questions] Trouble with init/1 spec

Kostis Sagonas kostis@REDACTED
Wed Mar 24 17:40:39 CET 2010


Jay Nelson wrote:
> 
> On Mar 24, 2010, at 9:00 AM, Kostis Sagonas wrote:
> 
>>  The type
>>
>>     [string() | non_neg_integer()]
>>
>> constrains the input argument better than list()
>>
>>>  Declaring it as list(any()) means the fields on the record have to 
>>> all be declared any().  As long as my port field is declared 
>>> non_neg_integer() in the record definition, I can't get past the 
>>> dialyzer warning.
>>
>> Huh?  Are you sure?  The record fields can be declared whatever type 
>> you want.  I am not sure to what dialyzer warning you are referring 
>> to, but perhaps we can take this off list.
> 
> I didn't state that too clearly.  The list(any()) caused dialyzer to 
> deduce that the record assignment was creating an any() value in a 
> field, therefore my record declaration each field needs to be any() 
> rather than string() or non_neg_integer().
> 
> If I make the arglist [string() | non_neg_integer()], then I have to 
> declare all my string() fields in the record to be of the same type 
> because of the record constructor assignments which is really misleading 
> to label a server name or user name as a non_neg_integer() and propagate 
> that to any functions that access the field.
> 
> Right now the only way to get around it easily is to make my port field 
> a string() and do the list_to_integer/1 conversion every time I access 
> it.  That way all the fields in the init/1 list just happen to become 
> string().

I really have no idea what you are referring to...  Have you actually 
tried the above (if so, some example code showing the dialyzer warning 
will help me see what the trouble is), or you are just assuming that you 
will have to do them?

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}}.
---------------------------------------------------------------

run dialyzer as follows:

% dialyzer jay.erl
   Checking whether the PLT /home/kostis/.dialyzer_plt is up-to-date... yes
   Proceeding with analysis... done in 0m4.38s
done (passed successfully)

and as you can see I got no warnings from dialyzer.

I've even changed the spec to:

-spec init([string() | integer()]) -> {ok, #twfsm_state{}}.

and still got no warnings from dialyzer.


I really want to understand this.  What exactly is that you claim you 
cannot really do without getting a dialyzer warning?

Kostis


More information about the erlang-questions mailing list