Proposal: Warn on duplicated specs

30 views
Skip to first unread message

eksperimental

unread,
Apr 4, 2021, 8:13:17 PM4/4/21
to elixir-l...@googlegroups.com
Hi,
I would like to propose that the compiler emits a warning when specs
are duplicated.

defmodule DuplicatedSpecs do
@spec foo(arg) :: {:ok, arg} when arg: term
@spec foo(arg) :: {:ok, arg} when arg: term
def foo(term), do: {:ok, term}
end

The reason is that the duplicated line should either be removed or
corrected because the user meant something else.

Let me know what you all think,
Thank you

José Valim

unread,
Apr 5, 2021, 3:43:55 AM4/5/21
to elixir-l...@googlegroups.com
This is most likely the job of Dialyzer and tools working on typespecs to do. As they can do a better job at that.

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/606a561a.1c69fb81.6b97f.649dSMTPIN_ADDED_MISSING%40gmr-mx.google.com.

eksperimental

unread,
Apr 5, 2021, 8:38:37 AM4/5/21
to elixir-l...@googlegroups.com
On Mon, 5 Apr 2021 09:43:39 +0200
José Valim <jose....@dashbit.co> wrote:

> This is most likely the job of Dialyzer and tools working on
> typespecs to do. As they can do a better job at that.

There are cases where specs may be used for documentation purposes
only, and Dialyzer may not ever been run.

I actually came across this when I tried to fix a spec that I could
read from the docs was wrong, but when I corrected it, I ended up
creating a duplicate.
https://github.com/phoenixframework/phoenix_html/pull/332

I am not suggesting doing any any analysis on specs just checking for
duplicates, since this check can be done at compile time.

Allen Madsen

unread,
Apr 5, 2021, 9:48:36 AM4/5/21
to elixir-l...@googlegroups.com
I believe the way dialyzer works, you can write two specs and it's valid. For example:

@spec foo(1) :: "one"
@spec foo(2) :: "two"
def foo(1), do: "one"
def foo(2), do: "two"

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.

eksperimental

unread,
Apr 5, 2021, 9:53:47 AM4/5/21
to elixir-l...@googlegroups.com
On Mon, 5 Apr 2021 09:48:21 -0400
Allen Madsen <allen.c...@gmail.com> wrote:

> @spec foo(1) :: "one"
> @spec foo(2) :: "two"
> def foo(1), do: "one"
> def foo(2), do: "two"

Yes, but those would not be duplicated.
These would, and Dialyzer will error saying that "foo/1 has overlapping
domains"

@spec foo(1) :: "one"

Ben Wilson

unread,
Apr 5, 2021, 12:07:56 PM4/5/21
to elixir-lang-core
Right, and this is why I think Jose is arguing that this is a job for Dialyzer. The only way to know that two specs are duplicate is if they are logically duplicate. Elixir does not know about the logic of specs today, that's dialyzer's job. eg:

@type one :: 1
@spec foo(1) :: "one"
@spec foo(one) :: "one"

This is logically duplicate, but not AST level duplicate. You could special case things I suppose at the Elixir level and only care about AST level duplicates but this leaves out a lot of cases people probably care about:

@spec age(user :: %User{}) :: integer
@spec age(current_user :: %User{}) :: integer

Here we have specs that are basically duplicates, but there is a difference in the argument name.

eksperimental

unread,
Apr 5, 2021, 1:11:55 PM4/5/21
to elixir-l...@googlegroups.com
Thank you for the clarification Ben.
I am aware of that, I meant "duplicate at the AST level" in
my proposal.
Reply all
Reply to author
Forward
0 new messages