CONCEPT
        closures example

DESCRIPTION
        This document contains small examples of the usage of
        (lambda-)closures. For technical details see the closures(LPC)
        doc. For hints when to use which type of closure, see the end
        of this doc.


        Many Muds use 'details' to add more flavour. 'Details' are
        items which can be looked at, but are not implemented as own
        objects, but instead simulated by the environment.
        Lets assume that the function

          AddDetail(string keyword, string|closure desc)

        adds the detail 'keyword' to the room, which, when look at,
        returns the string 'desc' resp. the result of the execution of
        closure 'desc' as the detail description to the player.

        Now imagine that one wants to equip a room with magic runes,
        which read as 'Hello <playername>!\n" when looked at.
        Obviously

          AddDetail("runes", sprintf( "Hello %s!\n"
                                    , this_player()->QueryName()));

        is not sufficient, as the 'this_player()' is executed to early
        and just once: for the player loading the room.

        The solution is to use closures. First, the solution using
        lfun-closures:

          private string _detail_runes () {
            return sprintf("Hello %s!\n", this_player()->QueryName());
          }
            ...
          AddDetail("runes", #'_detail_runes);

        or with an inline closure:

          AddDetail("runes"
                   , (: sprintf("Hello %s!\n", this_player()->QueryName()) :)
                   );


        Simple? Here is the same code, this time as lambda-closure:

          AddDetail( "runes"
                   , lambda(0
                     , ({#'sprintf, "Hello %s!\n"
                                  , ({#'call_other, ({#'this_player})
                                                  , "QueryName" })
                       })
                   ));

        Why the extra ({ }) around '#'this_player'? #'this_player
        alone is just a symbol, symbolizing the efun this_player(),
        but call_other() needs an object as first argument. Therefore,
        the #'this_player has to be interpreted as function to
        evaluate, which is enforced by enclosing it in ({ }). The same
        reason also dictates the enclosing of the whole #'call_other
        expression into ({ }).
        Note also the missing #'return: it is not needed. The result
        of a lambda-closure is the last value computed.


        Another example: Task is to reduce the HP of every living in a
        room by 10, unless the result would be negative.
        Selecting all livings in a room is simply

          filter(all_inventory(room), #'living)

        The tricky part is to reduce the HP. Again, first the
        lfun-closure solution:

          private _reduce_hp (object liv) {
            int hp;
            hp = liv->QueryHP();
            if (hp > 10)
              liv->SetHP(hp-10);
          }
            ...

          map( filter(all_inventory(room), #'living)
                   , #'_reduce_hp)

        or as an inline closure:

          map( filter(all_inventory(room), #'living)
                   , (: int hp;
                        hp = liv->QueryHP();
                        if (hp > 10)
                          liv->SetHP(hp - 10);
                      :) );

        Both filter() and map() pass the actual array item
        being filtered/mapped as first argument to the closure.

        Now, the lambda-closure solution:

          map( filter(all_inventory(room), #'living)
          , lambda( ({ 'liv })
            , ({'#, , ({#'=, 'hp, ({#'call_other, 'liv, "QueryHP" }) })
                    , ({#'?, ({#'>, 'hp, 10 })
                           , ({#'call_other, 'liv, "SetHP"
                                           , ({#'-, 'hp, 10 })
                             })
                      })
              })
            ) // of lambda()
          );

        It is worthy to point out how local variables like 'hp' are
        declared in a lambda-closure: not at all. They are just used
        by writing their symbol 'hp . Same applies to the closures
        parameter 'liv .
        The lambda-closure solution is not recommended for three
        reasons: it is complicated, does not use the powers of
        lambda(), and the lambda() is recompiled every time this
        statement is executed!


        So far, lambda-closures seem to be just complicated, and in
        fact: they are. Their powers lie elsewhere.

        Imagine a computation, like for skill resolution, which
        involves two object properties multiplied with factors and
        then added.
        The straightforward solution would be a function like:

          int Compute (object obj, string stat1, int factor1
                                 , string stat2, int factor2)
          {
            return   call_other(obj, "Query"+stat1) * factor1
                   + call_other(obj, "Query"+stat2) * factor2;
          }

        Each call to Compute() involves several operations (computing
        the function names and resolving the call_other()s) which in
        fact need to be done just once. Using lambda-closures, one can
        construct and compile a piece of code which behaves like a
        Compute() tailored for a specific stat/factor combination:

          closure ConstructCompute (object obj, string stat1, int factor1
                                              , string stat2, int factor2)
          {
            mixed code;

            // Construct the first multiplication.
            // The symbol_function() creates a symbol for the
            // lfun 'Query<stat1>', speeding up later calls.
            // Note again the extra ({ }) around the created symbol.

            code = ({#'*, ({ symbol_function("Query"+stat1, obj) })
                        , factor1 });

            // Construct the second multiplication, and the addition
            // of both terms.

            code = ({#'+, code
                        , ({#'*, ({ symbol_function("Query"+stat2, obj) })
                               , factor2 })
                   });

            // Compile the code and return the generated closure.
            return lambda(0, code);
          }

        Once the closure is compiled,

          str_dex_fun = ConstructCompute(obj, "Str", 10, "Dex", 90);

        it can be used with a simple 'funcall(str_dex_fun)'.


DESCRIPTION -- When to use which closure?
        First, a closure is only then useful if it needn't to live any
        longer than the object defining it. Reason: when the defining
        object gets destructed, the closure will vanish, too.

        Efun-, lfun- and inline closures should be used where useful, as they
        mostly do the job and are easy to read. The disadvantage of lfun- and
        inline closures is that they make a replace_program() impossible
        - but since such objects tend to not being replaceable at all, this is
        no real loss.

        Lambda closures are needed if the actions of the closure are
        heavily depending on some data available only at runtime, like
        the actual inventory of a certain player.
        If you use lfun-closures and find yourself shoving around
        runtime data in arguments or (gasp!) global variables, it is
        time to think about using a lambda-closure, compiling the
        value hard into it.
        The disadvantages of lambda closures are clear: they are damn
        hard to read, and each lambda() statement requires extra time to
        compile the closure.


SEE ALSO
        closures(LPC), closure_guide(LPC), closures-abstract(LPC)
