I big for literals
support. However I can agree that “just adding it” isn’t good. I would expect that in the documentation for types before first mention of literals support there should be explanation like in your post.
In case we go for literals support, I wonder if also supported would be overlapped domains
(which is how dialyzer
calls it). Currently multiple @spec
are supported by ex_doc
, but not by dialyzer
.
This is important to clearly say what kind of input would give what result, for example:
@spec sample(input :: atom) :: {:ok, output :: String.t()}
@spec sample(input :: any) :: {:error, :not_yet_supported}
Of course it’s not an example from prod
, but imagine we use function generators and we want to do above i.e. explain what kind of input would work and what would fail:
for {input, output} <- data do
$ unquote(input) -> unquote(output)
def sample(unquote(input)), do: unquote(output)
end
$ any -> :error
def sample(_input), do: :error
# alternatively when output literals are not needed:
input_or = data |> Map.keys() |> Enum.reduce(&{:or, [], [&2, &1]})
$ unquote(input_or) -> {:ok, string}
for {input, output} <- data do
def sample(unquote(input)), do: unquote(output)
end
$ any -> :error
def sample(_input), do: :error
Also let’s say we write code like:
@spec sample(any) :: :{ok, any}
$ any -> {:ok, any}
def sample(data), do: {:ok, data}
How would it look like in documentation generated by ex_doc
? Would it prefer $
over @spec
or maybe it would use both?
I know it’s a beginning, but I believe such questions may be helpful when making a decision about final form and answers or code examples may give us some general preview of the whole idea, so we can may think about edge cases from our experience.
For example here is one. How 0-arity functions would look like in $
notation?
# if we have such general form:
$ input -> output
# then 0-arity annotation would be:
$ -> output
# or maybe
$ () -> output
Looking forward seeing it’s final form.