Typespecs in the form currently used in Elixir are not adding anything new to the language, nothing at all. They are using already existing feature of module attributes, i…e. the stuff you use with @ sign.
You can always add new syntax to the language itself, but if you do so it’s harder to remove it afterwards. Typespecs are now just data, and are treated as such, if they are ignored or changed altogether your programs will not break at all because they do not really affect your runtime.
I appreciate Elixir creator(s) keeping the language (fairly) small. Smaller is better.
My bad. I should have guessed, since I saw the @ sign used for other purposes as well. Thanks for clarifying this.
In TypeScript/Flow/MyPy, typespecs are just data, and are absolutely not used at runtime. The parts after the : or :: signs is just data attached to the function signature.
Types and specs in Elixir are not even used at compiletime, except that they get integrated into the compiled modules.
Then the can get evaluated using a tool called dialyzer, which is from the erlang/beam toolchain and not related to elixir (directly).
Since elixirc does not resolve types, but only stores the information of them into the module, it would telling some false story when they are inlined. As it is now, it is more or less obvious that they are an optional extra.
Also elixirs (and erlangs) type annotations are in a way powerfull that I can’t relly think a way of to express it inline while maintaining readability.
Consider this one (this is a single type and not 4!):
In JavaScript with Flow and Python 3 with MyPy, types are “inlined” but are not used by JavaScript or Python themselves. They are only used by the type checker (Flow for JavaScript and MyPy for Python 3). I don’t feel like it’s telling a “false story”. Users don’t seem confused by that approach.
But I can sympathize with your argument about readibility.
I don’t use Python or JavaScript, so I don’t know anything about that. But can you provide any examples that are as complex as my examples above?
Dialyzer types are not dependent ones, but the fact that you can specify an explicit set of return values without bothering with creating complete new types and conversion routines from that types into ordinary numbers (just as an example).
You’re right about pattern matching. Python and JavaScript don’t support matching. It’s probably the main reason why it’s possible to “inline” type specifications. In Elixir, it would awkward to “repeat” the type specification in each pattern. Thanks for answering.
I do not think there has. The main disadvantage of moving specs to a different file is that it is very easy to forget them (and then they for instance are not updated when the functions themselves are changed).
In a language that performs full compile-time type checking it is enforced that the types and the actual signatures match, but in Elixir this is not the case.