<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<!-- %% -->
<!-- %W  function.tex              GAP documentation             Thomas Breuer -->
<!-- %W                                                         & Frank Celler -->
<!-- %W                                                     & Martin Schönert -->
<!-- %W                                                       & Heiko Theißen -->
<!-- %% -->
<!-- %H  @(#)<M>Id: function.tex,v 4.13 2001/10/06 18:32:31 gap Exp </M> -->
<!-- %% -->
<!-- %Y  Copyright 1997,  Lehrstuhl D für Mathematik,  RWTH Aachen,   Germany -->
<!-- %% -->
<!-- %%  This file contains a tutorial introduction to functions. -->
<!-- %% -->
<P/>

<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Chapter Label="Functions">
<Heading>Functions</Heading>

You  have already  seen how to   use functions in the &GAP;  library,
i.e., how to apply them to arguments.
<P/>
In this section  you will see  how to  write  functions in  the &GAP;
language.  You will also see how to use the <K>if</K> statement and declare
local variables with the <K>local</K> statement in the function definition.
Loop constructions via <K>while</K> and <K>for</K> are discussed further, as are
recursive functions.


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Section Label="Writing Functions">
<Heading>Writing Functions</Heading>
<P/>
Writing a function that prints <C>hello, world.</C>  on the screen is a simple
exercise in &GAP;.
<P/>
<Example><![CDATA[
gap> sayhello:= function()
> Print("hello, world.\n");
> end;
function(  ) ... end
]]></Example>
<P/>
This function when called will only execute the  <C>Print</C> statement in the
second line.  This will  print the string  <C>hello, world.</C>  on the screen
followed by a  newline character <C>\n</C> that causes  the &GAP; prompt  to
appear  on the next  line rather  than  immediately following the printed
characters.
<P/>
The function definition has the following syntax.
<P/>
<K>function</K><C>( <A>arguments</A> ) <A>statements</A></C> <K>end</K>
<P/>
A function definition starts with the keyword <K>function</K> followed by
the formal parameter list <A>arguments</A> enclosed in parenthesis
<C>( )</C>.
The formal parameter list may be empty as in the example.  Several
parameters are separated by commas.  Note that there must be <E>no</E>
semicolon behind the closing parenthesis.  The function definition is
terminated by the keyword <K>end</K>.
<P/>
A &GAP; function is an expression  like an integer,  a sum or a list.
Therefore it may be assigned to a variable.  The terminating semicolon
in the  example   does not belong    to the  function  definition  but
terminates the  assignment  of the  function to the  name  <C>sayhello</C>.
Unlike in the case   of integers, sums, and  lists  the value of   the
function <C>sayhello</C> is echoed in the abbreviated fashion
<C>function( ) ... end</C>.
This shows the most  interesting part  of a function: its
formal parameter list (which is empty  in this example).  The complete
value of <C>sayhello</C> is returned if you use the function
<Ref Func="Print" BookName="ref"/>.
<P/>
<Example><![CDATA[
gap> Print(sayhello, "\n");
function (  )
    Print( "hello, world.\n" );
    return;
end
]]></Example>
<P/>
Note  the  additional   newline  character   <C>"\n"</C>  in  the
<Ref Func="Print" BookName="ref"/>
statement.  It is  printed after the object  <C>sayhello</C> to start a new
line. The extra <K>return</K>  statement is inserted  by &GAP; to simplify
the process of executing the function.
<P/>
The newly defined function <C>sayhello</C> is executed by calling <C>sayhello()</C>
with an empty argument list.
<P/>
<Example><![CDATA[
gap> sayhello();
hello, world.
]]></Example>
<P/>
However, this is not a typical example as no  value is returned but only a
string is printed.

</Section>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Section Label="If Statements">
<Heading>If Statements</Heading>

In the following example we define a function <C>sign</C> which determines
the sign of an integer.
<P/>
<Example><![CDATA[
gap> sign:= function(n)
>        if n < 0 then
>           return -1;
>        elif n = 0 then
>           return 0;
>        else
>           return 1;
>        fi;
>    end;
function( n ) ... end
gap> sign(0); sign(-99); sign(11);
0
-1
1
]]></Example>
<P/>
This example also introduces the <K>if</K> statement which is  used to execute
statements  depending  on  a  condition.   The  <K>if</K>  statement  has  the
following syntax.
<P/>
<K>if</K> <A>condition</A> <K>then</K>
    <A>statements</A>
<K>elif</K> <A>condition</A> <K>then</K>
    <A>statements</A>
<K>else</K>
    <A>statements</A>
<K>fi</K>
<P/>
There may be several <K>elif</K> parts.  The <K>elif</K> part as well as the <K>else</K>
part  of the  <K>if</K> statement may be omitted.   An  <K>if</K>  statement  is no
expression and  can therefore not be assigned to a variable.  Furthermore
an <K>if</K> statement does not return a value.
<P/>
Fibonacci numbers are defined recursively by <M>f(1) = f(2) =  1</M> and
<M>f(n) =  f(n-1) + f(n-2)</M> for <M>n \geq 3</M>.
Since functions in &GAP; may call themselves,
a function <C>fib</C> that computes Fibonacci numbers can be implemented
basically by typing the above equations. (Note however that this is a very
inefficient way to compute <M>f(n)</M>.)
<P/>
<Example><![CDATA[
gap> fib:= function(n)
>       if n in [1, 2] then
>          return 1;
>       else
>          return fib(n-1) + fib(n-2);
>       fi;
>    end;
function( n ) ... end
gap> fib(15);
610
]]></Example>
<P/>
There should be additional tests for the  argument  <C>n</C> being  a positive
integer.   This  function <C>fib</C> might  lead to strange  results if called
with other arguments.  Try inserting the necessary tests into this example.

</Section>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Section Label="Local Variables">
<Heading>Local Variables</Heading>

A function <C>gcd</C> that computes the greatest common divisor of two
integers by Euclid's algorithm will need a variable in addition to the
formal arguments.
<P/>
<Example><![CDATA[
gap> gcd:= function(a, b)
>       local c;
>       while b <> 0 do
>          c:= b;
>          b:= a mod b;
>          a:= c;
>       od;
>       return c;
>    end;
function( a, b ) ... end
gap> gcd(30, 63);
3
]]></Example>
<P/>
The additional  variable <C>c</C>  is declared as  a  <E>local</E>  variable in the
<K>local</K> statement  of the function definition.  The <K>local</K> statement, if
present, must  be the first  statement of  a function  definition.   When
several local variables are  declared in only one  <K>local</K> statement they
are separated by commas.                                 
<P/>
The  variable <C>c</C>  is  indeed  a local  variable,  that  is local to  the
function <C>gcd</C>.  If you try  to use the value of <C>c</C> in the main loop you
will see that <C>c</C>  has no assigned value unless you have already assigned
a value to the variable <C>c</C>  in  the  main loop.  In this case  the local
nature of <C>c</C> in the function <C>gcd</C> prevents  the value of the <C>c</C> in the
main loop from being overwritten.
<P/>
<Example><![CDATA[
gap> c:= 7;;
gap> gcd(30, 63);
3
gap> c;
7
]]></Example>
<P/>
We say  that in a given scope an identifier identifies a unique variable.
A <E>scope</E> is a lexical part of a program text.  There is the global scope
that encloses  the  entire program text, and there are local  scopes that
range from the <K>function</K>  keyword, denoting the beginning of  a function
definition, to the corresponding <K>end</K> keyword.  A local scope introduces
new  variables, whose identifiers are  given in the formal argument  list
and the local declaration of the function.  The usage of an identifier in
a program text refers to  the  variable in  the  innermost scope that has
this identifier as its name.

</Section>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Section Label="Recursion">
<Heading>Recursion</Heading>

We have already seen recursion in the function <C>fib</C>
in Section&nbsp;<Ref Sect="If Statements"/>.
Here is another, slightly more complicated example.
<P/>
We will now write a function to determine  the number of partitions of
a positive integer.  A partition of a positive integer is a descending
list  of numbers   whose sum   is the   given   integer.  For  example
<M>[4,2,1,1]</M> is a partition of 8. Note that there is just one partition
of 0, namely <M>[ ]</M>. The complete set of all  partitions of an integer
<M>n</M> may be divided  into subsets with respect  to the largest element.
The number  of  partitions of   <M>n</M> therefore  equals  the  sum of the
numbers of partitions of <M>n-i</M> with elements less than or equal to <M>i</M>
for all possible <M>i</M>.  More generally the  number of partitions of <M>n</M>
with elements less than <M>m</M> is the sum of the numbers of partitions of
<M>n-i</M> with elements less than <M>i</M> for <M>i</M> less than <M>m</M> and <M>n</M>.  This
description yields the following function.
<P/>
<Example><![CDATA[
gap> nrparts:= function(n)
>    local np;
>    np:= function(n, m)
>       local i, res;
>       if n = 0 then
>          return 1;
>       fi;
>       res:= 0;
>       for i in [1..Minimum(n,m)] do
>          res:= res + np(n-i, i);
>       od;
>       return res;
>    end;
>    return np(n,n);
> end;
function( n ) ... end
]]></Example>
<P/>
We wanted to  write a function that  takes one argument.   We solved  the
problem of determining the number  of partitions in  terms of a recursive
procedure with two arguments.  So we had to write  in fact two functions.
The  function  <C>nrparts</C> that  can  be  used  to  compute the  number  of
partitions indeed takes only one  argument.  The  function <C>np</C> takes two
arguments and solves the problem in the indicated way.  The  only task of
the function <C>nrparts</C> is to call <C>np</C> with two equal arguments.
<P/>
We made <C>np</C> local to <C>nrparts</C>.  This  illustrates the possibility of
having local functions in &GAP;.  It is  however not necessary to put
it there.  <C>np</C> could as well  be defined on  the main level, but then
the  identifier <C>np</C> would  be bound and could   not be used for other
purposes, and if  it were used  the  essential function <C>np</C> would  no
longer be available for <C>nrparts</C>.
<P/>
Now have a look at the function <C>np</C>. It has two local variables <C>res</C>
and <C>i</C>. The  variable <C>res</C> is  used to collect the sum  and <C>i</C> is a
loop  variable. In the loop the  function <C>np</C> calls itself again with
other arguments. It would be very disturbing if this call of <C>np</C> was
to use the same <C>i</C> and <C>res</C> as the calling <C>np</C>.  Since the new call
of <C>np</C> creates a new scope with new variables this is fortunately not
the case.
<P/>
Note that the formal parameters <A>n</A> and <A>m</A> of <C>np</C> are treated like
local variables.
<P/>
(Regardless   of the recursive structure of   an algorithm it is often
cheaper (in    terms  of  computing    time)  to  avoid  a   recursive
implementation if possible (and it  is possible in this case), because
a function call is not very cheap.)

</Section>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Section Label="Further Information about Functions">
<Heading>Further Information about Functions</Heading>

The function  syntax is described  in Section <Ref Chap="Functions" BookName="ref"/>.   The <K>if</K>
statement is described  in more detail in  Section <Ref Sect="If" BookName="ref"/>.  More  about
Fibonacci  numbers is found  in  Section <Ref Func="Fibonacci" BookName="ref"/>  and more  about
partitions in Section <Ref Func="Partitions" BookName="ref"/>.

</Section>
</Chapter>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<!-- %% -->
<!-- %E -->

