Wheres the idiomatic place to add type specs?

Hi

I’m wondering what is the best practice for type specs. Keep them all in one place or keep them close to their usage?

I remember seeing somewhere, an example, where the types was defined on top of the module. For me it makes sense to keep the type specs away from the functions, because its not the thing i need to know. I can just hover and get the type of the method if i want to.

/J

I put specs between a function’s doc and its declaration. “Hover for spec” is editor/IDE-dependant. I imagine there is no objective best practice. I like to have the spec close to the function, espectially when reading new code. This is also how I see it in all codebases/libraries that I can remember.

@doc """
"""
@spec like_this() :: return_type()
def like_this do
 # ...
end
3 Likes

Yes, like @slouchpie I would keep the function spec (@spec, @callback, @macrocallback) close to the function and put the custom type specs (@type, @typep, @opaque) at the top of my module, e.g.

defmodule Foo.Bar do
  use Baz

  @type foo_result :: {atom, String.t()}
  @typep private_type :: {atom, atom, atom}

  ...

  @doc """
  Random function
  """
  @spec random_function(integer) :: foo_result
  def random_function(input) do
    ...
  end
end
3 Likes

Sounds like a good plan.

The practice that @moogle19 has suggested is also what’s practiced in the Elixir standard library, e.g. here: elixir/enum.ex at master · elixir-lang/elixir · GitHub

2 Likes