Procedural elements: ==================== definition of terms: : zero or more values to be evaluated. : one value to be evaluated as branch or loop condition. : one value to be evaluated at the end of the execution of the form; the value is returned. : local variable/parameter, global variable, or an indexed lvalue. : one value to be evaluated. : an integer constant : a string constant, or 0. used EBNF operators: { } iteration [ ] option | alternative forms: ({#', }) ({#'? { } [ ] }) ({#'?! { } [ ] }) ({#'&& { test } }) ({#'|| { test } }) ({#'while }) loop while test evaluates non-zero. ({#'do }) loop till test evaluates zero. ({#'= { } }) assignment other assignment operators work too. case_label: | | #'default generalized_case_label: case_label | #'.. case_label_list: case_label | ({ { generalized_case_label } }) case_delimiter: #', | #'break ({#'switch { case_label_list case_delimiter } }) Evaluate expression, then evaluate the result form labeled with the value equal to the value evaluated from expression. If no matching label exists, the value of #'switch is 0. lisp similars: #', progn #'? cond #'&& and #'|| or #'while do /* but lisp has more syntactic candy here */ #'= setq A parameter / local variable 'foo' is referenced as 'foo , a global variable as ({#'foo}) . In lvalue positions (assignment), you need not enclose global variable closures in arrays. Call by reference parameters are given with ({#'&, }) Some special efuns: #'[ indexing #'[< indexing from the end #'negate unary - Unbound lambda closures ======================= These closures are not bound to any object. They are created with the efun unbound_lambda() . They cannot contain references to global variables, and all lfun closures are inserted as is, since there is no native object for this closure. You can bind and rebind unbound lambda closures to an object with efun bind_lambda() You need to bind it before it can be called. Ordinary objects can obly bind to themselves, binding to other objects causes a privilege violation(). The point is that previous_object for calls done from inside the closure will reflect the object doing bind_lambda(), and all object / uid based security will also refer to this object. The following is mostly vapourware. Well, another application would be that some things in the driver can be, sort of, microprogrammed. The master object could set some hooks in inaugurate_master(), like creating the code for move_object(), using a primitive low_move_object() or __move_object() or such. All calls of init(), exit(), etc. can thus be controlled on mudlib level. The driver would do an implicit bind_lambda() to the victim when the closure is used. e.g. ({#'?, ({#'=, 'ob, ({#'first_inventory, 'destination}) }), ({#'do, ({#'call_other, 'ob, "init"}), ({#'=, 'ob, ({#'next_inventory, 'ob}) }), 0 }) }) or ({#'filter_objects, ({#'all_inventory, 'destination}), "init"}) /* Won't show init failures due to move/destruct */ is equivalent to if (ob = first_inventory(destination) ) { do { ob->init(); } while(ob = next_inventory(ob) ); } and it's speed is mainly determined by the call_other. Thus, it shouldn't be noticably slower than the current C code in move_object().