I am working with behaviours and callbacks, so I am trying to define a spec for a function that should accept an argument which is also a function, but specifically a function that accepts 1 argument. I just discovered that there is a is_function that can be used in a guard clause: https://hexdocs.pm/elixir/Kernel.html#is_function/2
I have something like this:
@callback something(fun :: function()) :: list()
and implementations look like this:
@impl true
def something(fun) do
fun.("abc")
end
It is important that the provided fun has an arity of 1. I could make a guard clause:
@impl true
def something(fun) when is_function(fun, 1) do
fun.("abc")
end
but I am wondering if it is possible to define this in the @callback spec?
As of now, the only type check that happens at compile time is determined by guards and pattern matching in function definitions (if I understand correctly how these new checks happen), not based on typespecs.
generally typespecs are not enforced in the BEAM at all. The function/arity typespecs are kind of deficient and (IMO) incorrect as implemented in dialyzer currently, I made an opinion video about here: https://www.youtube.com/watch?v=_XSRsYSwNpQ
Well elixir is dynamically typed so the checks aren’t done at compile time as such but the compiler adds code which do the checks in the patterns and guards. The compiler quite happily ignores all your type specs though you can use the dialyzer tool which will try to check your code and warn you if it finds errors.