Define and implement a behaviour in the same module

251 views
Skip to first unread message

Jack Rowlingson

unread,
Dec 5, 2017, 12:44:40 PM12/5/17
to elixir-lang-core
I had attempted to the following usage:


iex(1)> defmodule MyApp.Calculator do
...(1)>   @behaviour __MODULE__
...(1)>   @callback add(integer(), integer()) :: integer()
...(1)>   def add(x, y), do: x + y
...(1)> end
warning: behaviour MyApp.Calculator is undefined

After some discussion with Muskala (micmus)/Milde (lostkobrakai) it seemed that use case may be possibly be valid. That is, the ability to define and implement a behaviour in the same module.

For my part, I had wanted to locate the documentation and @callback along with the default implementation. I have been diligently factoring my modules into separate files per http://blog.plataformatec.com.br/2015/10/mocks-and-explicit-contracts/. With this approach, however, I am finding that there has been a bit of an explosion with the number of files.

It was suggested that the following is considered an idiomatic way to associate doc with an implementation:

defmodule MyApp.Calculator do
  @callback add(integer(), integer()) :: integer()

  defmacro __using__ do
    quote do
      def add(x, y), do: x + y
    end
  end
end

defmodule MyApp.CalculatorImpl do
  use MyApp.Calculator
  @behaviour MyApp.Calculator
end

But here too I need to define a second file for the default implementation (assuming one module definition per file is desired). I find that there is also a bit of additional complexity here which makes it slightly more difficult to reason about.

Note: Related? https://groups.google.com/forum/#!topic/elixir-lang-core/8jrwjECcFTw

Jack

José Valim

unread,
Dec 5, 2017, 12:58:02 PM12/5/17
to elixir-l...@googlegroups.com
Since behaviours are also validated by the Erlang compiler and tools like dialyzer, I don't believe we can make this work without first adding support for this directly to Erlang/OTP.



José Valim
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/e246a0c6-17fe-4403-8d2d-165f934e9be0%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages