[erlang-questions] Type def and spec syntax

Kostis Sagonas kostis@REDACTED
Sun Oct 2 20:42:08 CEST 2016


On 10/02/2016 12:56 AM, Robert Virding wrote:
> Is there any better documentation of type defs and specs than that which
> occurs in the Erlang Reference manual? If so where is it?

In light of recent discussions on this mailing list, I wish that those 
who complain about documentation took a bit of time to tell us which 
aspects of the current documentation they find unsatisfactory and why.

It's very difficult to know how to make something "better" if one does 
not get told why it's not good enough as it is.


> I am trying to define an equivalent type/spec syntax for LFE so I am
> going through the valid syntax then trying to work out what they mean.

OK, here is a thing I try hard to teach students who take my compiler 
courses: Do NOT mix up in your mind(s) syntax and semantics of a 
language. They are certainly not the same thing; they may not even be 
related in any way.

So it's not particularly surprising that you cannot "work out what they 
mean" by looking at the valid syntax of types and specs.


> And there is a lot of strangeness from simple things like the predefined
> type names are 'reserved' so this is valid:
>
> -type atom(X) :: list(X).
>
> (whatever it means) to much more strange things like:
>
> -spec foo(Y) -> integer() when atom(Y).
> -spec foo(Y) -> integer() when atom(Y :: integer()).
>
> (whatever they mean) neither of which are mentioned in the docs.

First of all, why should the above be mentioned in the reference manual, 
especially if they are "strange"?

Second, why do you find the first of these examples strange?  Erlang has 
been designed so that e.g. functions do not have just some alphanumeric 
sequence of characters as a name but their name includes an arity.  This 
means that length/1 is reserved (you cannot redefine it), while length/3 
is not.

In this prism, why do you find it strange that the atom/1 type is not? 
(Only atom/0 is.)


As to what the above examples mean, well it's very simple:

  - The type declaration defines a polymorphic type called atom that is 
an alias for the built-in polymorphic type list.  Granted that it's a 
very stupid name for this type, but there is nothing that forces good 
naming convensions in Erlang.  I can certainly define a length/3 
function that takes integer() arguments and returns a binary() of some sort.

  - The first foo/1 spec has no meaning because you cannot use the 
atom/1 type as a subtype constraint.  In fact, if you put this spec in a 
file and try to compile it, you will get a warning, which is consistent 
with the (very bad IMO) philosophy of the Erlang compiler to not refuse 
to compule code which is damn stupid.  If you use dialyzer on this spec, 
you will discover that this tool is more sane as far as tolerating 
constructs which have no meaning.  You will get a dialyzer error in this 
case.

  - The second foo/1 spec is rejected even by the compiler.  Have you 
actually tried this and the compiler accepted it?


> So is there a more complete and understandable documentation some where?

Suggestions on how to make the current documentation more complete and 
understandable are welcome!

Kostis



More information about the erlang-questions mailing list