Why there are no `Boolean.t()` and `Integer.t()` types?

I think it’s quite common in Elixir to use MyModule.t() for type specs. Elixir docs for example suggest using String.t() and Range.t() types.

Yet, there is no such thing as Integer.t() or Boolean.t(). For these two, we expect everyone to use integer() / boolean(). Why? :wink: Why don’t we add those missing type specs?

Asking, because quite regularly, some devs (including myself) forget about that inconsequence and mistakenly write Integer.t(). Only after somebody else’s code review I realise that it’s wrong and I have to correct it.

Additional types are only added when they add to the set of typespecs, not to just alias existing ones. String.t might technically only alias binary, but it adds the context of denoting specifically UTF-8 encoded data, as opposed to arbitrary encoded binaries. None of the String modules functions is meant to work with binaries, which are not UTF-8 encoded.

That’s why there’s no Integer.t, because there’s no need for it.

1 Like

Because String.t() is conceptually different than binary() (though it probably could be :unicode.unicode_binary() nowadays instead).

About why there is no Boolean.t(), mostly because there is existing alias that does that boolean() :: true | false and there is no Boolean module at all. Creating whole module only for sake of single type spec that already exists is a little bit too much in my book.

In short:

  • If it is built in type (as “in VM built in”) - there is built-in spec (with few exceptions like iodata() or boolean())
  • If it is compound type (like Range.t() which is in fact just a struct) - then there is Module.t() type
5 Likes