Elixir - Why is a type specification required in an @callback definition?

It appears that when you define the behavior, you need to include type specifications in the @callback definition. Then, when you accept the behavior, the compiler requires that function_name/arity be defined, but is completely happy if you do not follow type specifications.

My questions:

  • Are these observations correct?
  • If so, why are the @callback specifications a @callback type with the actual functionality of checking that function_name/arity ? This makes it difficult to understand what documentation is and what is the core functionality. The rest of the elixir seems to explicitly separate the two, preserving type specifications as an optional addition.

For instance:

If we omit the type specifications, we get a compilation error

 defmodule Greeting do @callback hello(person) end # (CompileError) iex:82: type specification missing return type: hello(person) 

To make the compiler happy, we must include type specifications:

 defmodule Greeting do @callback hello(%Person{}) :: {:ok, String.t} | {:error, String.t} end 

Now that we accept the behavior, the compiler checks that function_name/arity defined:

 defmodule WesternGreeting do @behaviour Greeting def hello(), do: "Howdy" end # warning: undefined behaviour function hello/1 (for behaviour Greeting) 

However, all type specifications in @callback are not taken into account by the compiler:

 defmodule WesternGreeting2 do @behaviour Greeting def hello([a, b, c]), do: a <> b <> c end # No warnings or errors 
+5
source share
2 answers

Calls @callback the same as @spec , it expects types. If in the first example you determine the type of the return value, it will not work either:

 iex(1)> defmodule Greeting do ...(1)> @callback hello(person) :: any() ...(1)> end ** (CompileError) iex:2: type person() undefined 

About type checking, I suppose it's not done yet

0
source

In older versions of erlang, this was not required. Somewhere along the line (I don’t remember exactly when) I realized that if you add them, then Dialyzer can perform an additional check.

In addition, you can get types from a module at runtime, which has some use.

https://www.youtube.com/watch?v=7lT4_E6dooQ

0
source

Source: https://habr.com/ru/post/1275475/


All Articles