Testing Private Functions

It is possible in some cases. Compiler needs to be able to prove that (for example) in every possible case the code f.() will be called with f equals fn -> IO.puts "hello" end. In BEAM languages, it is very hard to come up with such proof.

For example, if my code looks like

defmodule X do
  def adder(y) do
    fn x -> x + y end
  end

  def add(x, y) do
    adder(y).(x)
  end
end

Compiler can prove that adder(y).(x) always equals to (fn x -> x + y end).(x) or just x + y. (However, in order for this to happen, you need to add the @compile :inline)

But if I do something like

defmodule X do
  def adder(y) do
    fn x -> x + y end
  end
end

defmodule Y do
  def add(x, y) do
    X.adder(y).(x)
  end
end

Compiler can’t prove it. And it can’t prove it, because module X can change in runtime (due to hot-reloading) independently from Y, and this feature is a hard requirement of the runtime


That may sound like a problem, but honestly, runtime overhead of anonymous function dispatch is extremely low and can’t be noticed in any real world program. For example, the way your code fits into CPU cache has much more impact on performance, and this thing is nearly random.

2 Likes