[erlang-questions] Trouble with init/1 spec

Jay Nelson jay@REDACTED
Wed Mar 24 22:19:23 CET 2010


On Mar 24, 2010, at 1:34 PM, Kostis Sagonas wrote:
> Yes, this would have indeed helped, but I do not see how this error  
> is relevant/related to the input arguments of the spec, which  
> triggered this discussion.  The dialyzer warnings you got clearly  
> state that:
>
>   1) there is an error in the return type of function init/1
>   2) the function has no local return and
>   3) there is some type violation in the record construction.

I got this, but took the declaration of any() to mean that I was  
willing to stick any kind of object into a field declared to accept  
only string().
>
> Nothing of these is related to whether the spec for init/1 has  
> arguments of type list(any()) or something else.

I had a two line function that failed on the return value, which was  
initialized only from the input args (and the implicitly defined  
fields) so I believed the input args caused the failure.  If the  
error message had indicated only the implicitly initialized field was  
in error, I would have corrected my record definition.  The size of  
the record prevented me from visually matching all the constraints in  
the output.

>
> The type any() means "anything goes".  It's possible that you are  
> not fully aware of what specs and type declarations in records do.  
> They put extra constraints that have to be compatible with the  
> types that dialyzer infers (the so called "success typings"). An  
> inferred type of any() for some record field is compatible with a  
> user declaration that the field is of type string().  If  
> compatible, the strongest of the two -- in this case string() -- is  
> used from then on.

Yes, I have this backwards.  I thought any() meant the code may try  
to put any type of value, so no constraints can be applied.  In my  
example, I thought I had declared the field 'port' to accept only  
integer() values, but the value of the arg being supplied could be  
any term.  That was why I thought it failed.

Rather than restricting the types, the arguments of a function  
declare the widest acceptable range and if by inference the type can  
be restricted after the binding, the restriction is used as the  
inferred type.  Does this only apply to the special case of records?

I get no error for the following code:

-module(jay).
-export([init/1, foo/1]).

-spec init(any()) -> integer().		
init(Val) -> Val.

-spec foo(string()) -> integer().
foo(Val) -> init(Val).


Should dialyzer complain about this code?  If not, what is the  
interpretation?

jay



More information about the erlang-questions mailing list