[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