Hello, I would like to propose the addition of a new feature to Elixir.
Suppose a team created the following module defmodule A do defmacro __using__(_opts) do quote do def task(:coffee), do: "make coffee" def task(:cookies), do: "make cookies" end end end Now, a developer in some other team creates the following module defmodule MyModule do use A end This module allows to make coffe or cookies, and this is a good thing. Now suppose that after some time, someone else makes finds the next module useful defmodule B do defmacro nice_macro() do quote do def task(x), do: "something good is done, but sometimes there are hidden missiles being launched" end end end and modifies `MyModule` like this import B defmodule MyModule do use A B.nice_macro() end Oops!!! Very bad things can happen now if `MyModule.bar/1` is called with anything but `:coffee` or `:cookies`. This situation can be called an "unexpected clause problem" because it makes an existing function to be inadvertently redefined by code defined sometime and somewhere else. The proposed solution to this problem is to introduce the `defnotoverridable` clause, like this defmodule A do defmacro __using__(_opts) do quote do def task(:coffee), do: "make coffee" def task(:cookies), do: "make cookies" defnotoverridable [task: 1] end end end or like this, by declaring all existing functions at some point to be not overridable defmodule A do defmacro __using__(_opts) do quote do def task(:coffee), do: "make coffee" def task(:cookies), do: "make cookies" defnotoverridable :all end end end Note that a `defnotoverridable :all` can also be a strong guarantee against a missing `defnotoverridable`, like by doing defmodule B do defmacro __using__(_opts) do quote do defnotoverridable :all # defend just in case task/1 was previously defined at the macro call site def task(x), do: "something good is done, but sometimes there are hidden missiles being launched" end end end Furthermore: 1) a `defnotoverridable` cannot be undone by a subsequent `defoverridable`, but a `defoverridable` can be undone by a subsequent `defnotoverridable` (the point is, `defoverridable` indicates a possibility, whereas `defnotoverridable` indicates an impossibility) 2) a `defnotoverridable [foo: 1]` requires function `foo/1` to have been defined before I hope you find this addition useful. Thanks, Mário Guimarães -- 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+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/a72a057b-35db-414b-8f15-43952420910c%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.