Closure Guide for LPC

Table of Contents

        1 Indroduction, Overview and Efun-Closures

        2 Lfun-, Inline and Lambda-Closures
        2.1 Lfun-Closures
        2.2 Inline-Closures
        2.3 Lambda-Closures
        2.3.1 Advantages of Lambda-Closures
        2.3.2 Free Variables in Lambda-Closure Constructs
        2.3.3 Special Efun-Closures and Operator-Closures for Lambdas
        2.4 Closures with Strange Names
        2.5 Operator-Closures
        2.6 Variable-Closures

        3 Examples
        3.1 Lfun-Closure
        3.2 Lambda-Closure

1 Introduction, Overview and Efun-Closures

  A closure is a pointer to a function. That means that it is data like an
  int or a string are. It may be assigned to a variable or given to anoth-
  er function as argument.

  To create a closure that points to an efun like write() you can write
  the name of the efun prepended with "hash-tick": #'. #'write is a clo-
  sure that points to the efun write().

  I very often put parentheses around such a closure-notation because
  otherwise my editor gets confused by the hashmark: (#'write). This is
  especially of interest within lambda-closures (see below).

  A closure can be evaluated (which means that the function it points to
  is called) using the efuns funcall() or apply(), which also allow to
  give arguments to the function. Example:

    funcall(#'write,"hello");

  This will result in the same as write("hello"); alone. The string
  "hello" is given as first (and only) argument to the function the clo-
  sure #'write points to.

  The return value of the function the closure points to is returned by
  the efun funcall() or apply(). (Since write() always returns 0 the re-
  turn value of the example above will be 0.)

  What are closures good for? With closures you can make much more univer-
  sally usable functions. A good example is the function filter().
  It gets an array and a closure as arguments. Then it calls the function
  the closure points to for each element of the array:

    filter(({ "bla","foo","bar" }),#'write);

  This will call write("bla"), write("foo") and write("bar") in any order;
  the order is undefined.
  (In the current implementation the given closure is evaluated for all
  elements from the first to the last, so the output will be "blafoobar".)

  Furthermore the efun filter() examines the return value of each
  call of the function the closure points to (the return value of the
  write()s). If the value is true (not 0) then this element is put into
  another array which filter() builds up. If the return value is
  false (== 0) then this element is _not_ put into this array. When all
  calls are done the slowly built up array is returned. Thus,
  filter() filters from the given array all elements that the given
  closure evaluates "true" for and returns an array of those. (The array
  given to filter() itself is _not_ changed!)

  A more sensical example for filterwould be this:

    x = filter(users(),#'query_is_wizard);

  users() is an efun that gets no arguments and returns an array of all
  logged in players (wizards and players). query_is_wizard() is a
  simul_efun that gets an object as first (and only) argument and returns
  true (1) if this object is a wizard and 0 otherwise.

  So, for each element of the array returned by users() the function
  query_is_wizard() is called and only those for which 1 was returned are
  collected into the result and then put into the variable x.

  We now have all logged in wizards stored as array in the variable x.

  Another example: We want to filter out all numbers that are greater than
  42 from the array a of integers:

    x = filter(({ 10,50,30,70 }),#'>,42);

  (x will now be ({ 50,70 }).)

  Here two things are new: first: we create a closure that points to an
  operator; second: we use the possibility to give extra arguments to
  filter().

  Like all efuns the usual operators can be pointed to with a closure by
  prepending #' to them. funcall(#'>,4,5) is exactly the same as (4>5).

  The extra arguments given as third to last argument (as many as you
  like) to filter() are given as second to last argument to the
  function pointed to by the closure each time it is called.

  Thus we now call (({ 10,50,30,70 })[0]>42), (({ 10,50,30,70 })[1]>42) ...
  (which is (10>42), (50>42) ...) and return an array of all elements this
  returns true for and store it into x.

  If you want to create a closure to an efun of which you have the name
  stored in a string you can create such an efun-closure with the efun
  symbol_function():

    symbol_function("write") // this will return #'write

    funcall(symbol_function("write"),"foobar");  // == write("foobar");

  This function does not very often occur in normal code but it is very
  useful for tool-programming (eg the robe uses symbol_function() to allow
  you call any efun you give).

2 Lfun- and Lambda-Closures

  Very often the possibilities closures to efuns offer are not sufficient
  for the purpose one has. In nearly all cases three possibilities exist in
  such cases: use an lfun- or inline-closure, or a lambda-closure.

2.1 Lfun-Closures

    The first possibility is rather easy: like with the efun-closures you
    can create a pointer to a function in the same object you are by using
    the #' to prepend it to a function name of a function declared above.
    Example:

      status foo(int x) {
        return ((x*2) > 42);
      }

      int *bar() {
        return filter(({ 10,50,30,70 }),#'foo);
      }

    Thus, #'foo is used like there was an efun of this name and doing the
    job that is done in foo().

2.2 Inline Closure

    Inline closures are a variant of lfun closures, the difference being
    that the function text is written right where the closure is used,
    enclosed in a pair of '(:' and ':)'. The compiler will then take care
    of creating a proper lfun and lfun-closure. The arguments passed to
    such an inline closure are accessible by position: $1 would be the
    first argument, $2 the second, and so on. With this, the
    above example would read:

      int * bar() {
        return filter(({ 10,50,30,70 }), (: ($1 * 2) > 42 :));
      }

    or alternatively:

      int * bar() {
        return filter(({ 10,50,30,70 }), (: return ($1 * 2) > 42; :));
      }

    The difference between the two versions is that in the first form the text
    of the inline closure must be an expression only, whereas in the second
    form any legal statement is allowed. The compiler distinguishes the two
    forms by the last character before the ':)': if it's a ';' or '}', the
    compiler treats the closure as statement(s), otherwise as expression.

    Inline closures may also nested, so that the following (not very useful)
    example is legal, too:

      return filter( ({ 10, 50, 30, 70 })
                         , (: string *s;
                              s = map(users(), (: $1->query_name() :));
                              return s[random(sizeof(s))] + ($1 * 2);
                            :));

    The notation of inline closures is modelled after the MudOS functionals,
    but there are a few important differences in behaviour.


2.3 Lambda-Closures

    Lambda-Closures take the idea of 'define it where you use it' one step
    further. On first glance they may look like inline closures with an uglier
    notation, but they offer a few increased possibilities. But first things
    first.

    The efun lambda() creates a function temporarily and returns a closure
    pointing to this function. lambda() therefor gets two arrays as
    arguments, the first is a list of all arguments the function shall expect
    and the second array is the code of the function (in a more or less
    complicated form; at least not in C- or LPC-syntax). The closure #'foo
    from the example above could be notated as lambda-closure:

      lambda(({ 'x }),({ (#'>),
                         ({ (#'*),'x,2 }),
                         42
                      }))

    Now, the first argument is ({ 'x }), an array of all arguments the
    function shall expect: 1 argument (called 'x) is expected. Notice the
    strange notation for this argument with one single leading tick. Like
    The hash-tick to denote closures the leading tick is used to denote
    things called "symbols". They do not differ much from strings and if
    you do not want to have a deeper look into closures you can leave it
    this way.

    The second argument is an array. The first element of such an array
    must be an efun- or an lfun-closure, the further elements are the
    arguments for the function this closure points to. If such an argu-
    ment is an array, it is treated alike; the first element must be a
    closure and the remaining elements are arguments (which of course
    also might be arrays ...).

    This leads to a problem: sometimes you want to give an array as an
    argument to a function. But arrays in an array given to lambda() are
    interpreted as code-arrays. To allow you to give an array as an argu-
    ment within an array given to lambda(), you can use the function
    quote() to make your array to a quoted array (a quoted array is for
    an array what a symbol is for a string):

      lambda(0,({ (#'sizeof),
                  quote(({ 10,50,30,70 }))
               }))

    For array constants, you can also use a single quote to the same
    effect:

      lambda(0,({ (#'sizeof),
                  '({ 10,50,30,70 })
               }))

    This lambda-closure points to a function that will return 4 (it will
    call sizeof() for the array ({ 10,50,30,70 })). Another thing: if
    we want to create a function that expects no arguments, we can give
    an empty array as first argument to lambda() but we can give 0 as
    well to attain this. This is just an abbreviation.

    Lambda-closure constructs can become quite large and hard to read. The
    larger they become the harder the code is to read and you should avoid
    extreme cases. Very often the possibility to use an lfun or an inline
    instead of a large lambda shortens the code dramatically. Example:

      status foo(object o) {
        return environment(o)->query_level()>WL_APPRENTICE;
      }

      x=filter(a,#'foo);

    does the same as

      x=filter(a,lambda(({ 'o }),
                              ({ (#'>),
                                 ({ (#'call_other),
                                    ({ (#'environment),'o }),
                                    "query_level"
                                 }),
                                 WL_APPRENTICE
                              })));

    (Note that the syntax with the arrow "->" for call_other()s cannot be
    used, #'-> does not exist. You have to use #'call_other for this and
    give the name of the lfun to be called as a string.)

    This example also demonstrates the two disadvantages of lambda closures.
    First, they are very difficult to read, even for a simple example like
    this. Second, the lambda closure is re-created everytime the
    filter() is executed, even though the created code is always the
    same.

    'Why use lambdas at all then?' you may ask now. Well, read on.


2.3.1 Advantages of Lambda Closures

    The advantages of lambdas stem from the fact that they are created
    at runtime from normal arrays.

    This means that the behaviour of a lambda can be made dependant on data
    available only at runtime. For example:

      closure c;
      c = lambda(0, ({#'-, ({ #'time }), time() }) );

    Whenever you now call this closure ('funcall(c)') it will return the
    elapsed time since the closure was created.

    The second advantage of lambdas is that the arrays from which they
    are compiled can be constructed at runtime. Imagine a customizable prompt
    which can be configured to display the time, the environment, or both:

      mixed code;

      code = ({ "> " });
      if (user_wants_time)
        code = ({ #'+, ({ #'ctime }), code });
      if (user_wants_environment)
        code = ({ #'+, ({#'to_string, ({#'environment, ({#'this_player }) }) })
                     , code });
      set_prompt(lambda(0, code));


2.3.2 Free Variables in Lambda-Closure Constructs

      You can use local variables in lambda constructs without declaring
      them, just use them. The only limitation is that you at first have
      to assign something to them. Give them as symbols like you do with
      the arguments. This feature does not make much sense without the use
      of complexer flow controlling features described below.

      The closure #'= is used to assign a value to something (like the
      LPC-operator = is).

2.3.3 Special Efun-Closures and Operator-Closures for Lambdas

      There are some special closures that are supposed to be used only
      within a lambda construct. With them you can create nearly all code
      you can with regular LPC-code like loops and conditions.

      #'? acts like the "if" statement in LPC. The first argument is the
          condition, the second is the code to be executed if the condition
          returns true. The following arguments can also be such couples of
          code-arrays that state a condition and a possible result. If at
          the end there is a single argument, it is used as the else-case
          if no condition returned true.

          lambda(({ 'x }),({ (#'?),             // if
                             ({ (#'>),'x,5 }),  //    (x > 5)
                             ({ (#'*),'x,2 }),  //       result is x * 2;
                             ({ (#'<),'x,-5 }), // else if (x < -5)
                             ({ (#'/),'x,2 }),  //    result is x/2;
                             'x                 // else result is x;
                          }))

      #'?! is like the #'? but it negates all conditions after evaluation
           and thus is like an ifnot in LPC (if there were one).

      #', (which looks a bit strange) is the equivalent of the comma-operator
          in LPC and says: evaluate all arguments and return the value of
          the last. It is used to do several things inside a lambda-closure.

          lambda(({ 'x }),({ (#',),  // two commas necessary!
                                     // one for the closure and one as
                                     // delimiter in the array
                             ({ (#'write),"hello world!" }),
                             ({ (#'say),"Foobar." })
                          }))

      #'while acts like the LPC statement "while" and repeats executing one
              code-array while another returns true.
              #'while expects two or more arguments: the condition as first
              argument, then the result the whole expression shall have after
              the condition turns false (this is in many cases of no interest)
              and as third to last argument the body of the loop.

              lambda(0,({ (#',),            // several things to do ...
                          ({ (#'=),'i,0 }),    // i is a local variable of this
                                               // lambda-closure and is
                                               // initialized with 0 now.
                          ({ (#'while),
                             ({ (#'<),'i,10 }),   // condition: i < 10
                             42,                  // result is not interesting,
                                                  // but we must give one
                             ({ (#'write),'i }),  // give out i
                             ({ (#'+=),'i,1 })    // increase i
                          })
                       }))

               The function this closure points to will give out the
               numbers from 0 to 9 and then return 42.

      #'do is like the do-while statement in LPC and is very much like the
           #'while. The difference is that #'while tests the condition al-
           ready before the body is evaluated for the first time, this means
           that the body might not be evaluated even once. #'do evaluates
           the body first and then the condition, thus the body is evaluated
           at least one time.
           Furthermore, the arguments for #'do are changed in order. #'do
           expects as first to last but two the body of the loop, then the
           condition (as last-but-one'th argument) and the result value as
           last argument. So #'do must have at least two arguments: the
           condition and the result.

           lambda(0,({ (#',),          // several things to do ...
                       ({ (#'=),'i,0 }),  // i is a local variable of this
                                          // lambda-closure and is initialized
                                          // with 0 now.
                       ({ (#'do),
                          ({ (#'write),'i }),  // give out i
                          ({ (#'+=),'i,1 })    // increase i
                          ({ (#'<),'i,10 }),   // condition: i < 10
                          42                   // result is not interesting
                       })
                    }))

      NOTE: There is no #'for in LPC, you should use #'while for this.

      #'foreach is like the foreach() statement in LPC. It evaluates one or
           more bodies repeatedly for every value in a giving string, array
           or mapping. The result of the closure is 0.

           #'foreach expects two or more arguments:
            - a single variable symbol, or an array with several variable
              symbols
            - the value to iterate over
            - zero or more bodes to evaluate in each iteration.

           The single values retrieved from the given value are assigned
           one after another to the variable(s), then the bodies are executed
           for each assignment.

           lambda(0, ({#'foreach, 'o, ({#'users})
                                    , ({#'call_other, 'o, "die" })
                     }));

           lambda(0, ({#'foreach, ({'k, 'v}), ({ ...mapping...})
                                    , ({#'printf, "%O:%O\n", 'k, 'v })
                     }));

      #'return gets one argument and acts like the "return" statement in LPC
               in the function that is created by lambda(). It aborts the
               execution of this function and returns the argument.

               lambda(0,({ (#'while),// loop
                           1,        // condition is 1 ==> endles loop
                           42,       // return value (which will never be used)
                           ({ (#'write),"grin" })
                           ({ (#'?!),               // ifnot
                              ({ (#'random),10 }),  //       (random(10))
                              ({ (#'return),100 })  //   return 100;
                           })
                        }))

                This function will enter an endles loop that will in each
                turn give out "grin" and if random(10) returns 0 (which will
                of course happen very soon) it will leave the function with
                "return 100". The value 42 that is given as result of the
                loop would be returned if the condition would evaluate to 0
                which cannot be. (1 is never 0 ;-)

      #'break is used like the "break" statement in LPC and aborts the exe-
              cution of loops and switches.
              It must not appear outside a loop or switch of the lambda
              closure itself, it cannot abort the execution of the function
              the closure points to!

                lambda(0,({ (#'?),
                            ({ (#'random),2 }),
                            ({ (#'break) }), // this will cause the error
                                             // "Unimplemented operator break
                                             // for lambda()"
                            "random was false!"
                         }));

              You can use ({ #'return,0 }) instead of ({ #'break }) in such
              cases.

      #'continue is used like the "continue" statement in LPC and jumps to
                 the end of the current loop and continues with the loop
                 condition.

      #'default may be used within a #'switch-construct but be careful!
                To call symbol_function("default") (which is done usually
                by tools that allow closure-creation) might crash the
                driver! So please do only use it within your LPC-files.
                (NOTE: This driver bug is fixed somewhere below 3.2.1@131.)

      #'.. may be used within a #'switch-construct but is not implemented
           yet (3.2.1@131). But #'[..] works well instead of it.

      #'switch is used to create closures which behave very much like the
               switch-construct in LPC. To understand the following you
               should already know the syntax and possibilities of the
               latter one (which is mightier than the C-version of switch).

               I will confront some LPC versions and the corresponding clo-
               sure versions below.

               LPC:                  Closure:
                 switch (x) {          lambda(0,({ (#'switch), x,
                 case 5:                           ({ 5 }),
                   return "five";                  ({ (#'return),"five" }),
                                                   (#',),
                 case 6..9:                        ({ 6, (#'[..]), 9 }),
                   return "six to nine";           ({ (#'return),
                                                      "six to nine" }),
                                                   (#',),
                 case 1:                           ({ 1 }),
                   write("one");                   ({ (#'write),"one" }),
                   // fall through                 (#',),
                 case 2:                           ({ 2,
                 case 10:                             10 }),
                   return "two or ten";            ({ (#'return),
                                                      "two or ten" }),
                                                   (#',),
                 case 3..4:                        ({ 3, (#'[..]), 4 }),
                   write("three to four");         ({ (#'write),
                                                      "three to four" }),
                   break;  // leave switch         (#'break),
                 default:                          ({ (#'default) }),
                   write("something else");        ({ (#'write),
                                                      "something else" }),
                   break;                          (#'break)
                 }                              }))

      #'&& evaluates the arguments from the first on and stops if one evalu-
           ates to 0 and returns 0. If none evaluates to 0 it returns the
           result of the last argument.

      #'|| evaluates the arguments from the first on and stops if one evalu-
           ates to true (not 0) and returns it. If all evaluate to 0 it
           returns 0.

      #'catch executes the closure given as argument, but catches any
           runtime error (see catch(E)). Optionally the symbols 'nolog,
           'publish and 'reserve may be given as additional arguments to
           modify the behaviour of the catch.

      #'sscanf acts similar to how a funcall would, but passes the third
           and following arguments as lvalues, that is, values which can
           be assigned to.

      #'= and the #'<op>= variants are also special because the first
           argument has to be an lvalue.

2.4 Closures with Strange Names

    #'negate is the unary minus that returns -x for the argument x.

             map(({ 1,2,3 }),#'negate)

             This returns ({ -1,-2,-3 }).

    #'[ is used for the things that in LPC are done with
             the []-operator (it indexes an array or a mapping).

             lambda(0,({ #'[,quote(({ 10,50,30,70 })),2 })) ==> 30
             lambda(0,({ #'[,([ "x":10;50, "y":30;70 ]),"x",1 })) ==> 50

    #'[< is the same as #'[ but counts the elements from the
               end (like indexing with [] and the "<").

    #'[..] returns a subarray of the argument from the one
             given index to the other given index, both counted from the
             beginning of the array.

    #'[..<]
    #'[<..]
    #'[<..<] same as above, but the indexes are counted from the end,

                lambda(0,({ #'[..<],
                            quote(({ 0,1,2,3,4,5,6,7 })),2,3
                         }))

                This will return ({ 2,3,4,5 }).
    #'[..
    #'[<.. same as above, but only the first index is given, the
               subarray will go till the end of the original (like with
               [x..]).

    #'({ is used to create arrays (as with ({ }) in LPC). All arguments
             become the elements of the array.

             lambda(0,({ #'({,
                         ({ (#'random),10 }),
                         ({ (#'random),50 }),
                         ({ (#'random),30 }),
                         ({ (#'random),70 })
                      }))

             This returns ({ random(10),random(50),random(30),random(70) }).

    #'([ is used to create mappings out of single entries (with seve-
               ral values) like the ([ ]) in LPC. Very unusual is the fact
               that this closure gets arrays as argument that are not eval-
               uated, although they are not quoted.

               lambda(0,({ #'([,
                           ({ "x",1,2,3 }),
                           ({ "y",4,5,6 })
                        }));

               This returns ([ "x": 1;2;3,
                               "y": 4;5;6 ]).

               However, the elements of the arrays are evaluated as lambda
               expressions, so if you want to create a mapping from values
               evaluated at call time, write them as lambda closures:

               lambda(0, ({ #'([, ({ 1, ({ #'ctime }) }) }) )

               will return ([ 1: <result of ctime() at call time ]).

               Arrays can be put into the mapping by quoting:

               lambda(0, ({ #'([, ({ 1, '({ 2 }) }) }) )

               will return ([ 1: ({ 2 }) ])


    #'[,] is nearly the same as #'[. The only difference
                     shows up if you want to index a mapping with a width
                     greater than 1 (with more than just one value per
                     key) directly with funcall(). Example:
                     funcall(#'[,([ 0:1;2, 3:4;5 ]),0,1)
                     This will not work. Use #'[,] and it will
                     work. If you want to use it in a lambda closure you
                     do not have to use #'[,] and #'[ will
                     do fine. On the other hand, #'[,] cannot
                     work with arrays, so in nearly all cases use #'[
                     and just in the described special case, use
                     #'[,].
                     This is a strange thing and I deem it a bug, so it
                     might change in the future.

2.5 Operator-Closures

    Most of the closures that are used for things which are done by opera-
    tors are in fact not operator-closures but efun-closures. But there are
    a few which do not have the state of efun-closures but are called
    "operator-closures". #'return is an example, a complete list of them is
    given below.

    These closures cannot be called directly using funcall() or apply() (or
    other efuns like filter()), but must appear only in lambda-con-
    structs.

      funcall(#'return,4);  // does not work! This will raise an
                            // Uncallable-closure error.
      funcall(lambda(0,     // this is a correct example
                     ({ (#'return),4 })
                    ));

    All operator-closures:
    #'&&
    #'||
    #',
    #'?
    #'?!
    #'=
    #'<op>=
    #'++
    #'--
    #'break
    #'catch
    #'continue
    #'default
    #'do
    #'foreach
    #'return
    #'sscanf
    #'switch
    #'while
    #'({
    #'([

    #'.. is very likely to be an operator closure too, but since it is
    not implemented yet, I cannot say for sure.

2.6 Variable-Closures

    All object-global variables might be "closured" by prepending a #' to
    them to allow access and/or manipulation of them. So if your object has
    a global variable x you can use #'x within a closure.

    Normally you will treat those expressions like lfun-closures: put them
    into an array to get the value:

    object.c:
              int x;
              int foo() {
                return lambda(0,({ (#'write),({ (#'x) }) }));
              }

    Anybody who now calls object->foo() will get a closure which will, when
    evaluated, write the actual value of object's global variable x.

    Variable closures do not accept arguments.

3 Examples

  In this section I will give and explain some examples coming out of
  praxis. If the explanation seems to be in some cases too detailed this
  can be explained by the trial to allow the reader to read the examples
  section first ;-)

3.1 Lfun-Closure

    An item with a complex long-description like a watch that shall always
    show the actual time will usually base upon the complex/item-class and
    give an lfun-closure as argument to the set_long()-method.

    watch.c:
             inherit "complex/item";

             string my_long() {
               return ("The watch is small and has a strange otherworldly"
                       " aura about it.\n"
                       "The current time is: "+ctime()+".\n");
             }

             void create() {
               set_short("a little watch");
               set_id(({ "watch","little watch" }));
               set_long(#'my_long);  // the lfun-closure to the lfun my_long()
             }

3.2 Lambda-Closure

    The example from 3.1 can also be written using a lambda-closure.

    watch.c:
             inherit "complex/item";

             void create() {
               set_short("a little watch");
               set_id(({ "watch","little watch" }));
               set_long(lambda(0,({ (#'+),
                                    "The watch is small and has a strange"
                                    " otherworldly aura about it.\n"
                                    "The current time is: ",
                                    ({ (#'+),
                                       ({ (#'ctime) }),
                                       ".\n"
                                    })
                                 })));
             }
