mirror of
https://github.com/ldmud/ldmud
synced 2026-08-12 14:26:05 -04:00
explicit was mispelled as explicite in a few places implicit was mispelled as implicite in a few places attachment was mispelled attachement in a few places
131 lines
4.4 KiB
Text
131 lines
4.4 KiB
Text
CONCEPT
|
|
inline closures
|
|
|
|
SYNTAX
|
|
function <returntype> ( <arguments> ) : <context> { <code> }
|
|
|
|
(: <statements> ; <expr>, ... , <expr> :)
|
|
|
|
|
|
DESCRIPTION
|
|
Inline closures are a way to program closures which are
|
|
compiled at the time an object is loaded, but can access
|
|
values from their enclosing function at runtime.
|
|
|
|
Example:
|
|
|
|
closure factory (int arg) {
|
|
return function int (int val) { return val * arg; };
|
|
}
|
|
|
|
closure f1 = factory(2);
|
|
closure f2 = factory(3);
|
|
funcall(f1, 3) -> will yield 6.
|
|
funcall(f2, 3) -> will yield 9.
|
|
|
|
The closure here 'inherits' the current value of the local
|
|
variable 'arg' at the time the closure is created. These
|
|
values are called the "context" of the closures - they are
|
|
stored in a special set of variables in the closure.
|
|
|
|
One specific feature of the closure context is that it can be
|
|
changed from within the closure, and that these changes remain
|
|
permanent:
|
|
|
|
closure factory (int arg) {
|
|
return function int (int val) { return val * arg++; };
|
|
}
|
|
|
|
closure f = factory(2);
|
|
funcall(f, 3) -> will yield 6.
|
|
funcall(f, 3) -> will now yield 9!
|
|
|
|
But changes of the closure context will not reflect on the
|
|
local variable it was copied from and vice versa.
|
|
|
|
In addition to the implicit context inherited from the
|
|
defining function, additional context variables can be defined
|
|
in the closure:
|
|
|
|
closure factory (int arg) {
|
|
return function int (int val) : int x = 2 * arg
|
|
{ return val * x; };
|
|
}
|
|
|
|
closure f = factory(2);
|
|
funcall(f, 3) -> will yield 12.
|
|
|
|
It is possible to define multiple context variables with and
|
|
without initialisation:
|
|
|
|
closure factory (int arg) {
|
|
return function int (int val) : int y, x = 2 * arg;
|
|
int z
|
|
{ return val * x; };
|
|
}
|
|
|
|
These explicit context variables are useful when the closures
|
|
needs to keep a state, or to improve performance:
|
|
|
|
mapping m = ...;
|
|
closure slow (int arg) {
|
|
return function mixed () { return m[arg]; }
|
|
}
|
|
closure fast (int arg) {
|
|
return function mixed () : mixed val = m[arg] { return val; }
|
|
}
|
|
|
|
In the above example, the fast() function executes the lookup
|
|
m[arg] only once when the inline closure is created; the
|
|
slow() function on the other hand returns a closures which
|
|
looks up m[arg] every time it is called. A second effect is
|
|
that the results of the slow closure change when m changes;
|
|
the result of the fast closure is always the same.
|
|
|
|
|
|
In the definition of an inline closure, some elements are
|
|
optional:
|
|
|
|
<returntype> defaults to 'mixed'
|
|
( <arguments> ) defaults to '(mixed $1 ... mixed $9)'
|
|
: <context> no default
|
|
|
|
|
|
The special (: :) form is meant for simple expressions (and
|
|
MudOS compatibility). The form
|
|
|
|
(: <statements> ; <expr>, ..., <expr> :)
|
|
|
|
is the shorthand notation for
|
|
|
|
function { <statements>; return <expr>, ..., <expr>; }
|
|
|
|
For example the two statements
|
|
|
|
sort_array(arr, function { return $1 < $2; } )
|
|
sort_array(arr, (: $1 < $2 :) )
|
|
|
|
do the same. The example also demonstrates that both the <statements>
|
|
and the <expr> part in this form are optional.
|
|
|
|
|
|
|
|
NOTES
|
|
The macro __LPC_INLINE_CLOSURES__ is defined when the
|
|
inline closures as described here are available. If not
|
|
defined, the driver implements a more restricted version
|
|
('(: :)' syntax only, no context variables) for backwards
|
|
compatibility.
|
|
|
|
Inline closures are not to be confused with inline functions
|
|
known from other languages.
|
|
|
|
HISTORY
|
|
LDMud 3.2.7 implemented the older, restricted form of inline
|
|
closures.
|
|
LDMud 3.3.271 implemented the full form of inline closures.
|
|
LDMud 3.3.275 re-allowed statements in the (: :) form.
|
|
|
|
SEE ALSO
|
|
closures-abstract(LPC), closures-example(LPC), closure_guide(LPC)
|
|
closures(LPC)
|