4 ms·
Looks nice; I dig the $-prefixed type annotations. I also like that the types boil down to familiar conventions like atoms / atom-tagged tuples under the hood;
by yellowapple 2y ago
Looks nice; I dig the $-prefixed type annotations. I also like that the types boil down to familiar conventions like atoms / atom-tagged tuples under the hood; that's exactly how I'd expect an Erlang/Elixir type system to work, and is exactly how I already tend to use tagged tuples.
> If we get rid of this limitations, we could define head as follows:
$ non_empty_list(a) -> a
def head([head | _]), do: head
In this case, I ain't sure what the typespec is really contributing here:
- We can already infer the input type, thanks to Erlang/Elixir baking pattern-matching into function signatures
- We can already infer the output type, because there's only one possible output and it's coming directly from the input
This is exactly the problem I hit the last time I tried to chase down the "typespec ALL the things!" path with Dialyzer: the typespecs are just restating what's already obvious from looking at the function, making them redundant at best. Yeah, having a summary of the input and output types is valuable for more complex functions, but it's already a common Erlang (and Elixir, by descent from Erlang and Ruby) best practice to break down complex functions into smaller, simpler units, at which point the typespecs lose value again.
I'm probably missing something here, though - and maybe a more complicated example would better illustrate the value these typespecs add.