[NAME]
ALL.dao.routine.closure

[TITLE]
Anonymous Routine and Closure

[DESCRIPTION]

Dao supports routines as first class objects. So they can be created at running time and
used just like other objects. They may be created as anonymous routines or closures, depe
nding on how they are declared.

The syntax to declare an anonymous routine or closure is nearly identical to the definiti
on of a normal function, except the following differences: 
  *  No need for a function name;
  *  Its function body may access the local variables of the outer function; 


Here is a simple anonymous function, 
     
   1  rout = routine( name: string, value = 0 ){
   2      io.writeln( name, value )
   3      return name.size() + value
   4  }
   5  rout( "abc", 123 )
     
The only difference of this declaration from normal function declaration is the lacking o
f function name here. 

In the above example, the created routine does not access the local variables of the oute
r routine. So it is created as ordinary anonymous routine instead of closure. Here is ano
ther example where a local variable of the outer routine is accessed, 
     
   1  routine MakeClosure( start: int )
   2  {
   3      return routine( offset: int ){
   4          return start + offset
   5      }
   6  }
   7  rout = MakeClosure( 100 );
   8  rout( 123 )
     
Due to the access of local variable "start" of "MakeClosure()", the created routine "rout
" will be a closure. When a closure is created, it will store the accessed outer scope lo
cal variables as up values in the created routine. For primitive type variables, their cu
rrent value will be copied to the closure's up values; for other types, only their refere
nces are copied. Once a closure is created, it can work without the original context wher
e it was created.

The main difference between an anonymous function and a closure is whether it accesses th
e local variable of the outer function. This difference leads to another important differ
ence in what happens when an expression for running time routine creation is executed. If
the expression should produce a closure, a new routine with captured up values is always 
created; but if the expression should produce an ordinary anonymous routine, the same rou
tine might be returned. For example, the following "MakeRoutine()" function will always r
eturn the same routine object, 
     
   1  routine MakeRoutine()
   2  {
   3      return routine( value: double ){
   4          return value * value
   5      }
   6  }
   7  io.writeln( MakeRoutine(), MakeRoutine() )
     
This happens when the anonymous function has no static variables. If it has, a new routin
e is always created just like new routines are always created for closures. For example, 
the following "MakeRoutine()" function will always return a new routine object, 
     
   1  routine MakeRoutine()
   2  {
   3      return routine( value: double ){
   4          static dummy = 123
   5          return value * value
   6      }
   7  }
   8  io.writeln( MakeRoutine(), MakeRoutine() )