It is possible to return functions as value. This way you can build functions that construct special purpose functions according to some parameters. The tricky bit is what variables does the function see. The way this works in GEL is that when a function returns another function, all identifiers referenced in the function body that went out of scope are prepended a private dictionary of the returned function. So the function will see all variables that were in scope when it was defined. For example, we define a function that returns a function that adds 5 to its argument.
function f() = ( k = 5; `(x) = (x+k) )
	  Notice that the function adds k to
	  x.  You could use this as follows.
g = f(); g(5)
	  And g(5) should return 10.
        
	  One thing to note is that the value of k
	  that is used is the one that's in effect when the
	  f returns.  For example:
function f() = ( k := 5; function r(x) = (x+k); k := 10; r )
	  will return a function that adds 10 to its argument rather than
	  5.  This is because the extra dictionary is created only when
	  the context
	  in which the function was defined ends, which is when the function
	  f returns.  This is consistent with how you
	  would expect the function r to work inside
	  the function f according to the rules of
	  scope of variables in GEL.  Only those variables are added to the
	  extra dictionary that are in the context that just ended and
	  no longer exists.  Variables
	  used in the function that are in still valid contexts will work
	  as usual, using the current value of the variable.
	  The only difference is with global variables and functions.
	  All identifiers that referenced global variables at time of
	  the function definition are not added to the private dictionary.
	  This is to avoid much unnecessary work when returning functions
	  and would rarely be a problem.  For example, suppose that you
	  delete the "k=5" from the function f,
	  and at the top level you define k to be
	  say 5.  Then when you run f, the function
	  r will not put k into
	  the private dictionary because it was global (toplevel)
	  at the time of definition of r.
	
Sometimes it is better to have more control over how variables are copied into the private dictionary. Since version 1.0.7, you can specify which variables are copied into the private dictionary by putting extra square brackets after the arguments with the list of variables to be copied separated by commas. If you do this, then variables are copied into the private dictionary at time of the function definition, and the private dictionary is not touched afterwards. For example
function f() = ( k := 5; function r(x) [k] = (x+k); k := 10; r )
	  will return a function that when called will add 5 to its
	  argument.  The local copy of k was created
	  when the function was defined.
	
	  When you want the function to not have any private dictionary
	  then put empty square brackets after the argument list.  Then
	  no private dictionary will be created at all.  Doing this is
	  good to increase efficiency when a private dictionary is not
	  needed or when you want the function to lookup all variables
	  as it sees them when called.  For example suppose you want
	  the function returned from f to see
	  the value of k from the toplevel despite
	  there being a local variable of the same name during definition.
	  So the code
function f() = ( k := 5; function r(x) [] = (x+k); r ); k := 10; g = f(); g(10)
	  will return 20 and not 15, which would happen if
	  k with a value of 5 was added to the private
	  dictionary.