FUNCTION:

	This help file covers several aspects of functions:

		1) Introduction

		2) Variable scoping

		3) Function arguments

		4) Function return values

		5) Function recursion

		6) Special topics		

	1) Introduction ------------------------------------------------

	Functions are an essential part of the language. Learning how
	to create and use functions will greatly add to the benefits
	of using RLaB. 

	It is important to remember that functions adhere to the RLaB
	rule: "everything is a variable". Functions are variables, and
	like the other types or classes of variables in RLaB can be
	printed (although it will be hard to understand the output),
	copied, and renamed. Functions cannot act as operands to
	numeric operators, although the result of the function usually
	can. Since function calls are evaluated "in-place" they can be
	used within other expressions, for example:

	> sin(cos(1.0))
	    0.514

	> sin( [ cos(0.3), sqrt(cos(0.3)) ] )
	    0.817      0.829  


	The syntax used for function definition is a little unusual...

	Example:

	> sum = function (s) 
	  {
	    local(i, Sum);
	    Sum = 0;
	    for(i in 1:size(s)) {
	      Sum = Sum + s[i];
	    }
	    return Sum;
	  };
	>

	creates a function, and assigns it to the variable `sum'.
	Sum is invoked like:

	> sum( [1,2,3,4,5] )
		15

	2) Variable Scopes ---------------------------------------------

	When you start a RLaB session, either interactively or in
	batch-mode, you create an environment. The environment or
	workspace consists of the built-in functions, and any other
	variables or functions you may have added. The workspace will
	also be referred to as the global-symbol-table or the global
	scope. 

	There are two other types of environment available: a
	function's local environment and a file's static environment
	(we will use the term environment and scope interchangeably).

	A function's local scope is temporary, it is created when the
	function is invoked, and is destroyed when the function
	returns. A file's static scope is created when the file is
	loaded, and remains intact until the RLaB session is
	terminated. 

	The different scopes serve to protect data from operations
	that occur in the other scopes. There is some degree of
	overlap in order to allow flexibility. Functions can affect
	file-static and global scopes; statements within files can
	affect statements within other files and the global
	scope. More simply put, the "lower" scopes generally have
	access to the "higher" scopes. When a variable is used, RLaB
	uses certain rules to "bind" the variable. When we use the
	term bind or bound, we mean that the variable name is
	associated with an entry in one of the three types of symbol
	tables.

	File-Scope: Variables that are in a file (but not within a
		    function) are bound to the global-symbol-table
		    (global-scope or global-environment) unless a
		    static declaration is used. When a variable is
		    declared static (see `help static') it is bound to
		    the file's symbol table. From that point on, the
		    variable will remain bound to the file's
		    scope. When a variable is declared static, it is
		    not visible from the global environment or from
		    any other files.

	Function Local Scope: In general, variables used within a
		    function (other than the function's arguments) are
		    bound to the function's local scope (there are
		    ways to override this behavior). Variables bound
		    to a function's local scope are not visible from a
		    file's scope or from the global scope. They are
		    created (undefined) when the function is invoked,
		    and destroyed when the function returns.

		    There are exceptions: variables used in a function
		    context are bound to the global-symbol-table. For
		    example:

				x = a * sin ( pi )

		    `sin' is used in a function context, and is bound
		    to the global scope, while `x', `a', and`pi' are
		    bound to the function's local environment.

		    Function's that are defined within a file have
		    full access to the file's static variables.
		    Function variables will be bound to the file's
		    scope before local binding occurs. For example:

		    ---- beginning of file.r ----

		    static (A, pi)
		    A = 1.e-3;
		    pi = atan(1)*4;

		    fun = function ( a ) { return A*sin(pi*A*a); }

		    ---- end of file.r ----

		    When `fun' is created it binds `A' and `pi'
		    to file.r's static environment.

		    There are two declarations: `global' and `local'
		    that can be used to override the default behavior
		    if necessary. Variables declared local will be
		    bound to to the function's local scope, and
		    variable declared global will be bound to the
		    global scope.

		    **NOTE: There is one more special exception (for
		    advanced usage): Function variables can be
		    members of a list, or members of a list, that is a
		    member of another list, etc, etc... In effect this
		    allows users to hide or protect variables and
		    functions in an arbitrary manner. Thus, when RLaB
		    sees something like:

				ML.e1.signal( a )

		    it does not bind `ML' to the global scope. In this
		    context RLaB cannot bind the function until
		    runtime, so the list is by default bound to the
		    function's local scope. This behavior can be
		    changed by using the global, or static
		    declarations.
		    

	The built-in function fvscope performs a variable scope
	analysis of any user-function. For example:

	---- beginning of file.r ----
	static (stat)        // Keep track of some statistic.
	stat.n = 0;
	stat.total = 0;

	x = function (a, b)
	{
	  local (a)
	  global (pi)

	  for( i in 1:a.nr ) 
	  {
	    a[;i] = a[;i]*norm(a);
	  }
	  retv = 2*pi*norm(a)*b;
	  stat.n = stat.n + 1;
	  stat.total = stat.total + retv;

	  return << val = retv; avg = stat.total/stat.n >>;
	};
	---- end of file.r ----

	> local ("./file.r");
	> fvscope(x);
		Function Variable SCOPE analysis for : x
		Filename: ./jnk.r
	
		line	GLOBAL			ARG		LOCAL
	
		  10						Local-Var: i
		  10						Local-Var: a
		  12						Local-Var: a
		  12						Local-Var: i
		  12						Local-Var: a
		  12						Local-Var: i
		  12						Local-Var: a
		  12	Global-Var: norm
		  14						Local-Var: retv
		  14	Global-Var: pi*
		  14						Local-Var: a
		  14	Global-Var: norm
		  14				Arg-Var: b
		  15	Static-Var: stat
		  15	Static-Var: stat
		  16	Static-Var: stat
		  16	Static-Var: stat
		  16						Local-Var: retv
		  17						Local-Var: retv
		  17	Static-Var: stat
		  17	Static-Var: stat
	
	The function `x' is used to compute some arbitrary value. The
	list `stat' is used to keep track of how many times `x' is
	called, and to compute the average of the return
	value. fvscope shows us, line by line, each variable, and how
	it is bound.

	3) Function arguments ------------------------------------------

	RLaB supports both "pass by reference" and "pass by value" for
	passing arguments to a function. 

	Pass by reference means that the arguments, while still
	referred to be there declared names, are in fact bound to the
	caller's scope. Thus, the function can directly modify
	variables in the caller's scope.

	Pass by value means that a function cannot modify variables in
	the caller's scope - essentially, an argument that is passed
	by value is copied, and the copied value is passed to the
	function to operate on.

	Pass by reference can be considered the default behavior,
	since it takes no special effort on the user's part. Pass by
	value is achieved by declaring function arguments to be
	local. For example:

	// Pass by reference

	> myf = function ( A ) { A = "changed"; return A; }
		<user-function>
	> B=10;
	> myf(B);
	> B
	 B =
	changed

	// Pass by value
	> myf = function ( A ) { local (A) A = "changed"; return A; }
		<user-function>
	> B=10;
	> myf(B);
	> B
	 B =
	       10

	In the previous example B, a variable in the global workspace,
	is changed by myf (pass by reference). In the second part of
	the example, the function argument A, is redeclared to be
	local. This redeclaration forces the function argument to be
	passed by value.

	One advantage of this behavior is that users can create
	functions and selectively decide which variables should be
	passed by reference, and which should be passed by value.

				* * *

	You do not have to call a function with the same number of
	arguments specified in the definition. If you invoke a
	function with more arguments than declared, the result is an
	error. If you call the function with less arguments than
	declared, RLaB will pad the argument list with UNDEFINED,
	objects. Additionally, commas may be used to "skip" arguments
	that are unnecessary. for each argument that is "skipped" an
	UNDEFINED variable is passed to the function during execution.

	UNDEFINED arguments can be detected with the exist function,
	for example: 

      	if (!exist (ARG))
      	{
      	  ARG = 0;	// Initialize undefined argument
      	}
	
	The function-local variable `nargs' is automatically
	initialized to the argument number of the last specified
	argument in the function call. For example:

	testf = function ( a, b, c, d, e )
	{
	  nargin
	}

	> testf ( 1 , 2 );
	        2
	> testf ( 1 , , 2 );
	        3
	> testf ( 1 , , 2, 3 );
	        4

				* * *

	Lists can be used to get the effect of variable argument
	lists. If you are not familiar with lists, then now would be a
	good time to `help LIST'. A function can take a list as an
	argument and then pull the actual number of list elements, and
	their values, from the list when the function is called. For
	example:

	> vlistf = function( l )
	  {
	    local(i,x);

	    printf( "number of elements in variable arg-list = %i\n", size(l) );
	  
	    // Pull each element from the list
	  
	    for( i in 1:size(l) )
	    {
	      x = l.[i];
	      // now do something with x
	    }
	  };
	> vlistf( << "string"; [1,2;3,4] >> )
	number of elements in variable arg-list = 2
	
				* * *

	Functions can take other functions as arguments, for example:

	> trick = function ( a , b )
	  {
	    a(b)
	  };
	> trick( eye, [3,3] );
	 matrix columns 1 thru 3
	           1           0           0
	           0           1           0
	           0           0           1

	Note that the function name, passed as an argument, did not
	need quotes. This is so because functions are variables in the
	same sense as scalars, strings, and matrices. The variable a
	in the previous function example refers to the function eye,
	since function args are passed by reference.

	4) Function return values --------------------------------------

	All functions return a value, although the return statement is
	optional. If a return statement is not used, then the function
	will return 0 (zero) to the calling environment. If the return
	statement is used, the result of the return statement is
	passed back to the calling environment.

	Functions can only return a single entity to the calling
	environment. If it is necessary to return more than one
	entity, a list can be used to group multiple entities together
	for return.

	Example:

	We want to write a function that creates a set of matrices (a
	state-space model). We will write such a function, and group
	the separate matrices together in a list.

	> ss = function( w )
	  {
 	    local(A, B, n);
	    n = size( w )[1];
	    A = [ zeros(n,n), eye(n,n);
	          -w;         zeros(n,n) ];
	    B = ones(n,n);
 	
 	    return << A = A; B = B >>;
	  };
	>

	The return statement creates the list, and assign the names
	`A' and `B' to it's members.	

	Since functions are evaluated "in-place" their return values
	can be manipulated in the usual ways, for example:

	> eig(symm(rand(3,3))).val
	 val =
	   -0.937      0.571       1.81  

	> eig(symm(rand(3,3))).val[2]
	    0.191

	> rand(10,10)[1,3,5;2,4,6]
	     0.29      0.411      0.345  
	    0.561      0.686     0.0287  
	    0.269      0.324       0.57  

	5) Function recursion ------------------------------------------

	Functions can call themselves recursively. For a function to
	call itself recursively, the special keyword `$self' must be
	used. `$self' must be used because the statements within a
	function are compiled before the function is assigned to a
	variable. Therefore, the function cannot resolve a recursive
	reference without `$self'.

	Example:

	> fact = function (f) 
	  {
	    if(f <= 1) {
	      return 1;
	    else
	      return f*$self(f-1);
	    }
	  };
	> fact(10)
		3628800

	The local statement in the previous function makes `a' local
	to the function `x'. Since `a' is also a function argument, it
	is copied into the local variable `a', which is used for the
	throughout the function. As you can see `a' does not even show
	up as an argument variable in the output from fvscope. 

	Since `i' is not explicitly declared, it defaults to a local
	variable with initial value undefined. When the function
	returns the variable `i' (and all other local variables) will
	cease to exist. When x() is called again `i' (and all other
	local variables) will again be re-initialized undefined. The
	local statement must be the 1st statement in a function, and
	only one local statement is allowed. If you must declare alot
	of local variables, then break the local statement with a
	continuation. Note that `norm', although undeclared, is a
	global variable. This is because `norm' is a function. Since
	functions cannot be entirely local to another function it
	makes no sense to have to declare all functions global.

	The global statement tells the function to get `pi' from the
	global workspace. The global statement must follow the local
	statement, and precede any executable function statements.

	6) Special Topics ----------------------------------------------

		A) Although pass by reference is the default behavior
		for function arguments, there are some instances where
		this may not seem true (but it is). For example, when
		you pass part of a matrix into a function you cannot
		modify the original matrix.

		> x = function ( a ) { global (pi) a[1] = pi; }
			<user-function>
		> z=rand(2,2);
		> z
		 z =
		   0.0369      0.665  
		    0.162     0.0847  
		> x(z);
		> z
		 z =
		     3.14      0.665  
		    0.162     0.0847  
		> x(z[2]);
		> z
		 z =
		     3.14      0.665  
		    0.162     0.0847  
		> y
			UNDEFINED
		> x(y=z[2]);
		> y
		 y =
		     3.14  

		You can see that in the first function call, z is
		passed by reference. In the second call, the second
		element of z (z[2]) is copied into a temporary
		variable, which in turn is passed by reference to the
		function. In the last call the temporary variable is
		stored in the variable y, which as you can see, is
		passed by reference to the function for modification.

	----------------------------------------------------------------
