Proposal: @typep warnings when used in @spec and @type

44 views
Skip to first unread message

Andrew Summers

unread,
Feb 12, 2017, 12:03:03 PM2/12/17
to elixir-lang-core
Consider the following code:

defmodule Foo do
  @typep foo :: integer
  @type bar :: foo

  @typep re :: integer
  @type mi :: float | re
  @type la :: mi | nil

  @spec baz(integer) :: foo
  def baz(bat), do: bat
end

This code presents several problems, and in my opinion should generate
at least two different compiler warnings, or the semantic of typep
should be changed slightly.

1) When referencing Foo.bar in @specs externally, Dialyzer will
complain (correctly) that it cannot find Foo.foo, since that is not in
the namespace of the code using Foo.bar. This puts Foo.foo into a
pseudo-private state, where other code can see it via Foo.bar but
never actually use Foo.bar for typespecs because it references
Foo.foo.

Proposed warning: Cannot reference @typep in @type.

2) Though a more general case of 1, one should not be able to
indirectly reference a @typep via @type, as in the case of Foo.la
referencing Foo.re. I call this a shadowed @typep, but
have no particular claims to this name being optimal. Feel free to
change.

Proposed warning: Cannot reference shadowed @typep in @type.

3) Foo.bat should not, as a def, be able to reference a @typep in its
@spec. Supposing this were in an @callback, for example, there would
be no way to have an @spec in the implementation for the @behaviour
that would actually work, for similar reasons as above, since you
could never reference Foo.foo in a module besides Foo.

Proposed warning: Cannot reference @typep in @spec for def.

However, one could argue that a simple change in the semantic of
@typep would alleviate all of these issues. If @typep had a sort of
unfolding behavior, where it was simply a shorthand for types locally,
that eventually become their longer forms. So for example someone
referencing Foo.la would see integer | float | nil. I do not
personally like this, it seems rather counterintuitive to me, but I
can see an argument to be made for it.

As an example of how this was inconvenient for me recently, in Ecto
one can set up a module as a logger for Ecto.Repo queries.
would generate a warning when running dialyzer of:

Unknown types:
  'Elixir.IO.ANSI':ansicode/0

José Valim

unread,
Feb 12, 2017, 12:40:20 PM2/12/17
to elixir-l...@googlegroups.com
The current semantics of typep are directly inherited from Erlang and Typespecs. We could introduce our own pre-parsing but there is little benefit in doing so. We would need to reimplement a good part of the typespec processing, adding both code and time complexity to the codebase.

The best would be to start such a discussion on the Erlang/OTP side of things.



José Valim
Skype: jv.ptec
Founder and Director of R&D

--
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-core+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/1463dbf4-e96c-4d76-922e-ffaa54347152%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Andrew Summers

unread,
Feb 12, 2017, 12:58:23 PM2/12/17
to elixir-lang-core, jose....@plataformatec.com.br
That makes total sense, I will do so. Thanks José! 
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.

Michał Muskała

unread,
Feb 14, 2017, 11:51:04 AM2/14/17
to elixir-l...@googlegroups.com
Such a discussion (at least partially) is already happening in this PR: https://github.com/erlang/otp/pull/1337

Michał.
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/CAGnRm4J8t0JCuVxn%3DbPXRJ4zhCY%2Bj3TF7gmOEeEPD8GPg-PjjQ%40mail.gmail.com.
Reply all
Reply to author
Forward
0 new messages