tags:

views:

390

answers:

2

Why doesn't the Erlang compiler detect undefined functions in compile time.

If I write test.erl:

-module(test). 
-export([start/0]).

start() ->
       erlang:foo().

It compiles fine.

Eshell V5.6.5  (abort with ^G)
1> c(test).
{ok,test}
2>

But crashes runtime.

2> test:start().
** exception error: undefined function erlang:foo/0

Why doesn't the compiler issue an error or a warning about this during compilation? It should know about exported functions, shouldn't it?

A: 

I think that this is an implementation question as the Erlang developers decided to to runtime linking rather than build-time linking. Part of the reason may have something to do versioning and/or dynamic code loading.

Richard
+9  A: 

Erlang is a dynamic language. It is good practice however to do type checking and static analysis post-compilation.

The tool Dialyzer is used to check for this sort of error condition.

The reason the compiler doesn't know about it at compile time is because functions can be searched for and dynamically loaded from the code path at run time (and also from a remote node). The Dialyzer will check the code against the code path at the time it is run.

The ability to load code from a remote node means that basic 'systems' can be installed on a device and the device can then bootstrap itself from the network.

You should also remember another characteristic of Erlang that you can generate function calls on the fly using constructs like:

erlang:apply(ModuleName, FunctionName, ArgList)

so in that case it is simply not possible to know if the function exists at compile time or not.

And although the module and function might exist now at compile time, you can hot swap modules out and unload code, so it may not be there at run time.

Gordon Guthrie
Not only the code path but other nodes in an Erlang cluster. Code does not have to be local to be loaded in to an Erlang VM and executed.
Rob Elsner
I hadn't really thought about that. A quick look at the Erlang Cookbook turns up how to do it. http://www.trapexit.org/Remote_Code_Load
Gordon Guthrie
Also, you're free to replace or unload the module at runtime, so even if the compiler checked now, it could still fail later.
archaelus
Added your points and made the answer community wiki.
Gordon Guthrie