Home > erlang, programming > Erlang’s Dynamism

Erlang’s Dynamism

This is more verbose answer to @bubbafat twitt-question. It started lkie this:

  • @bubbafat: Functions used by spawn to start a process must be exported. Why doesn’t erl compiler error when this is missed?  #erlang
  • @danielllo: @bubbafat ‘cos it is possible to define and load  new modules later on during runtime in #erlang
  • @bubbafat: @danielllo Thx. Do you mean redefining the module at runtime or that the func might resolve in a different module loaded later? #erlang
  • @danielllo: You have many ways of referencing #erlang module:function not known at compile time.
    1. you can load the precompiled module at later time from a path not being provided to compiler.
    2. you can use M:F(Args) function invocation in #erlang, any of M, F, Args being variables dynamically referencing module, function and argument list.
    3. you can construct erlang AST tree programmaticaly, compile it at runtime and load the resulting beam.
    4. you can acheive the p.3 result using a helper tools such as LFE, Smerl or  “Dynamic” module generation with compile-time macros
    5. … and I’m sure there is more ;)
Categories: erlang, programming Tags:
  1. June 30th, 2009 at 09:34 | #1

    I know you didn’t mean to get sucked into a long discussion when you replied to my tweet - I appreciate that you’ve taken as much time as you have to respond. If you have a few more minutes I still have one question.

    I understand how the dynamic nature of Erlang can allow resolving the function later on when the module name is provided (M:F) or when the name is a variable.

    But when it’s a non-qualified local function name I’m still not seeing it - perhaps I am misunderstanding Erlangs scope or lifetime rules.

    Example:

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

    function() ->

    start() ->
    PID = spawn(foo, function, []),

    In that specific case - how is the reference resolvable later to something other than foo:function()? I did not indicate a module name and it’s not a variable … and using an atom doesn’t make sense there (to me, anyway). So it seems like it must be a function from the locally defined module (in which case validating that the function is exported should be trivial).

    I absolutely get that if the spawn had been:

    PID = spawn(foo, Variable, []),

    or

    PID = spawn(foo, othermodule:function, []),

    then resolving later is not just a feature - it’s mandatory to ensure that if the other module wasn’t loaded, or changed, etc that the call is updated.

    The only case I currently see (I’ve only been learning Erlang for a few days so there is a lot I don’t see yet) is the case where the current module (foo) changes (potentially redefining foo:function).

    But in that case wouldn’t the existing process continue to run with the old definition of the foo module (where the reference is still unambiguous)?

    Anyway - thanks again.

  2. June 30th, 2009 at 11:26 | #2

    On the way to work I decided the way Erlang does it is right.

    The example I gave was too simple. Once processes begin starting other processes and we create a fun that spawns a process and start calling that fun dynamically … well … resolving late is important.

    When the function was not in the export list the compiler gave me a warning that the function was never called. I should have heeded it.

  3. July 1st, 2009 at 10:33 | #3

    I’m glad to hear that. Anyway always happy to help :)

  1. No trackbacks yet.