A case for inline type annotations

Correct. There are several reasons for not inlining type annotations and you touched two of them:

  • Elixir already supports default arguments and pattern matching in signatures, adding a third component will make it confusing and hard to read, and your example shows it well

  • By keeping them together, it would be very easy to conflate implementation with specification. For example, if you accidentally remove one of the clauses while refactoring the hostname function, then type checking may still succeed. After all, if you keeping implementation and specification together, then you can accidentally remove both, and you won’t have a specification to catch such mistakes

You already posted a good example, let me post another one.


For example, imagine you are doing a payment integration that returns one of the following statuses:

$ type payment_status = :trial | {:success, metadata} | {:overdue, metadata}

You must likely have a function today that deals with those statuses like this:

def log_payment_status(:trial) do
  ...
end

def log_payment_status({:success, metadata}) do
  ...
end

def log_payment_status({:overdue, metadata}) do
  ...
end

One of the goals of the type system is to allow us to say that, if we add a new payment status, the code above should emit a warning. In this case, it doesn’t make sense to annotate inline, because each clause only handles part of the payments, and you want to guarantee it handles all statuses as a whole:

$ payment_status() -> ...
def log_payment_status(:trial) do
def log_payment_status({:success, metadata}) do
def log_payment_status({:overdue, metadata}) do

If we only had inline annotations, then you would be forced to rewrite the code above to this:

def log_payment_status(status :: payment_status()) :: ... do
  case status do
    :trial -> ...
    {:success, metadata} -> ...
    {:overdue, metadata} -> ...
  end
end

Which is fine, but not what we’d write today.


Modern and ergonomic is not about copying what other languages do, is about making sure it fits with the existing patterns and idioms in the language. :slight_smile:

37 Likes