How can I define named functions in the Elixir console without getting ** (ArgumentError) cannot invoke def/2 outside module?

Nathan Basanese picture Nathan Basanese · Feb 10, 2015 · Viewed 9.8k times · Source

I can define named functions in modules just fine, but I haven't yet got the hang of it for use in the iex> or ex> consoles.

I keep getting the following error when I try to run the def command:

(ArgumentError) cannot invoke def/2 outside module

pprime.exs

IO.puts "initial division test"

defmodule Expand do
    def transform(myvar) do
        8 * myvar + 3;
    end
end

div2 = fn inputnum ->
  [:a, inputnum/2.0, inputnum/3, inputnum/5.0, inputnum/7]
end

output = div2.(20.1)

I can run this with elixir just fine, as follows:

$ elixir pprime.exs

However, in the console, I can't seem to do any such thing:

Erlang/OTP 17 [erts-6.3] [source] [64-bit] [async-threads:10] [kernel-poll:false]

Interactive Elixir (1.0.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> def transform(myvar) do 8 * myvar + 3; end
** (ArgumentError) cannot invoke def/2 outside module
    (elixir) lib/kernel.ex:3556: Kernel.assert_module_scope/3
    (elixir) lib/kernel.ex:2816: Kernel.define/4
    (elixir) expanding macro: Kernel.def/2
    (elixir) iex:1: :elixir_compiler.__FILE__/2

How can I define a named function in the Elixir console?

Is this even possible?

Do I need to create a special module for using in the Elixir console?

Answer

José Valim picture José Valim · Feb 10, 2015

Short answer: You can't.

Long answer: All code in Elixir exist inside modules since many Elixir features, like hot code swapping, relies on having modules as the code container. That's why you can't define functions outside modules (there is no global, mutable namespace they could be added to).