Difference between anonymous and named functions?

As a statement that is incorrect. An anonymous function is attached to the module that creates it [source].

Execution of the anonymous function will force the module that created it to load - and if that module cannot be loaded, execution of the anonymous function will fail - no matter how simple that anonymous function might be.

Example session:

# File: alpha.ex
defmodule Alpha do

  def make_fun,
    do: fn -> "Greetings from module #{__MODULE__}" end

end

# File: bravo.ex
defmodule Bravo do
  def dessicate(fun, path) do
    File.write path, (:erlang.term_to_binary fun), [:binary]
  end

  def hydrate(path) do
    {:ok, content} = File.read path
    :erlang.binary_to_term content
  end
end

iex(1)> ls()
     alpha.ex
     bravo.ex
iex(2)> c("alpha.ex")
[Alpha]
iex(3)> c("bravo.ex")
[Bravo]
iex(4)> :code.is_loaded Alpha
{:file, :in_memory}
iex(5)> :code.is_loaded Bravo
{:file, :in_memory}
iex(6)> fun = Alpha.make_fun
#Function<0.111841791/0 in Alpha.make_fun/0>
iex(7)> fun.()
"Greetings from module Elixir.Alpha"
iex(8)> Bravo.dessicate fun, "greetings"
:ok
iex(9)> 
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
       (v)ersion (k)ill (D)b-tables (d)istribution
a
$ iex
iex(1)> ls()
      alpha.ex
      bravo.ex
      greetings
iex(2)> c("bravo.ex")
[Bravo]
iex(3)> :code.is_loaded Alpha
false
iex(4)> :code.is_loaded Bravo
{:file, :in_memory}
iex(5)> fun = Bravo.hydrate "greetings"
#Function<0.111841791/0 in Alpha>
iex(6)> fun.()
** (UndefinedFunctionError) undefined function
    #Function<0.111841791/0 in Alpha>()
iex(6)> c("alpha.ex")              
[Alpha]
iex(7)> fun.()       
"Greetings from module Elixir.Alpha"
iex(8)> :code.is_loaded Alpha          
{:file, :in_memory}
iex(9)> c("alpha.ex",".")              
warning: redefining module Alpha (current version defined in memory)
  alpha.ex:2
[Alpha]
iex(10)> c("bravo.ex",".")
warning: redefining module Bravo (current version defined in memory)
  bravo.ex:2
[Bravo]
iex(11)> ls()
     Elixir.Alpha.beam
     Elixir.Bravo.beam
     alpha.ex
     bravo.ex
     greetings
iex(12)> 
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
       (v)ersion (k)ill (D)b-tables (d)istribution
a
$ iex
iex(1)> ls()
     Elixir.Alpha.beam
     Elixir.Bravo.beam
     alpha.ex
     bravo.ex
     greetings
iex(2)> r(Bravo)
warning: redefining module Bravo (current version loaded from Elixir.Bravo.beam)
  bravo.ex:2

{:reloaded, Bravo, [Bravo]}
iex(3)> :code.is_loaded Alpha
false
iex(4)> :code.is_loaded Bravo
{:file, :in_memory}
iex(5)> fun = Bravo.hydrate "greetings"
#Function<0.111841791/0 in Alpha>
iex(6)> :code.is_loaded Alpha          
false
iex(7)> fun.()
"Greetings from module Elixir.Alpha"
iex(8)> :code.is_loaded Alpha
{:file, '/Users/wheatley/sbox/elx/trial/anon/Elixir.Alpha.beam'}
iex(9)>
2 Likes