[erlang-bugs] Inconsistent and incomprehensible handling of variables in spec's by compiler

Robert Virding <>
Fri Feb 17 10:54:41 CET 2012

If in my file I add the sepc:

-spec set_var(PrefixExp, Val, State) -> State.

I get the compiler errors, errors mind you, not warnings:

src/luerl_eval.erl:332: type variable 'PrefixExp' is only used once (is unbound) 
src/luerl_eval.erl:332: type variable 'Val' is only used once (is unbound)

but if I write it as:

-spec set_var(_PrefixExp, _Val, State) -> State.

then the compiler is happy and is quiet. If I write it as:

-spec set_var(Val, Val, State) -> State.

(which is wrongly from my point of view) or go all verbose and write:

-spec set_var(PrefixExp::any(), Val::any(), State::any()) -> State::any().

(which doesn't really add any useful information) the compiler is again happy and silent.

This is inconsistent and does not make sense for variables in a function spec. Either it is wrong, for some incomprehensible reason, to have singleton variables in a function spec, or it shouldn't matter what the variable names are. And why should adding a type, even the most general one, make a difference to the variable name usage. And why should the compiler be bothered with the function spec at all seeing it is doesn't use it and it is not part of the language.

In my naive view of the the typing world my original spec says that set_var/3 takes three arguments of any type and returns a value of the same type as the third argument. Then why not just add type information and make the compiler happy? Well in my case it doesn't give me anything; it makes the spec much longer and there is nothing in a type which would give me more information than is in the variable names. Also dialyzer doesn't actually *need* the spec as it works it out by itself anyway. And the type of PrefixExp is a big hairy recursive type which I am happy to let dialyzer work out for me. Typer gives me a half-screen long type for it.

I get the same behaviour when running dialyzer on the different versions. Again I don't understand why it behaves like that.


More information about the erlang-bugs mailing list