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, 'reserve and 'limit may be given as additional
           arguments to modify the behaviour of the catch.

      #'= 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
    #'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"
                                    })
                                 })));
             }
