Prev: Statements
Functions
Functions are a way to write repeatedly occuring computations only once, but use them wherever needed. They also help in structuring longer scripts into smaller, easily understandable units. By putting often occuring functions into separate modules (see section * ()), function libraries can be created.
Functions normally have a set of parameters as input and return a single function result as output. Since the function result can be an array, an arbitrary number of values can be returned.
The function is left by returning a value with a return statement. If the function is left by reaching its end, null is returned.
The following example declares a function sqrt computing the square root of a number x greater than or equal to 1, then calls it with parameters x=2 and x=9:
function sqrt(x)
y=x;
do
y0=y; y=(y+x/y)/2
until y>=y0;
return y
end // of function sqrt
print sqrt(2), sqrt(9)
→ 1.4142135624 3
|
This is quite a simple function with a single parameter x and a simple function result (the value of y).
Multiple parameters are separated by commas. The following function find finds the index of the first element in an array a with a value equal to x (there is a standard function for this: array.index).
function find(a, x)
i=0;
while i<len(a) and a[i]#x do
i++
end;
return i
end
print find([9, 11, 13], 11)
→ 1
print find([9, 11, 13], 8)
→ 3
|
A function can be recursive, i.e. can call itself: the following function clone returns a full copy of its parameter t. It uses array.copy to copy all the elements, and .isarray to test whether t is an array.
function clone(t)
if isarray(t) then
c=array.copy(t);
// recursively clone the elements
for i=0 to len(t)-1 do c[i] = clone(t[i]) end;
return c
else
return t
end
end
|
If a function returns an array, the call can be followed by expressions in brackets accessing certain elements:
a=['one':1, 'two':2, 'three':3];
print keys(a)[2]
→ three
|
Function parameters are like local variables; they can optionally be declared to hold an instance of a given class. Likewise, the function can be declared to return an instance. See * () for examples and details.
Optional Parameters
Optional parameters are parameters with a default value: if the parameter is omitted, the default value is assumed. The expression to compute the default value can be any expression which is valid in the global context (i.e. it cannot use a preceding function parameter). It is evaluated when the function is called, not when the function is declared.
When calling a function, the number of actual parameters must not be less than the number of mandatory parameters in the declaration of the function, and not be greater than the total number of declared parameters.
The following rewrites function find by adding an optional parameter start indicating the position to start searching at. The default value of start is 0, so calling find with only two parameters produces exactly the same result as before:
function find(a, x, start=0)
while start<len(a) and a[start]#x do
start++
end;
return start
end
print find([9, 11, 13], 11)
→ 1
print find([9, 11, 13], 11, 2) // start=2
→ 3
|
Functions with optional parameters can have options for simplified syntax in interactive use (see section * ()). Options are simply single character names for optional parameters.
function grow(years,interest=2) /i:interest
a=1;
while years>0 do
a+=a*interest/100; years--
end;
return a
end
grow(10,5)
→ 1.21899442
grow/i=5 10 // works only in interactive shells
→ 1.6288946268
|
Forward Declaration
Functions must be declared before they can be used. This means that if two functions call each other, at least one must be declared with forward and implemented later. In the following example, either f or g must be forward declared, since function f calls function g and vice versa:
function g(x, a=3.2) forward // g is made known
function f(x)
if x<3 then
return g(x*x) // g is called
else
return x+2
end
end
function g(x, a=3.2) // here g is declared
return f(x+a)
end
|
The default values of the optional parameters of the forward declared function are only used to mark optional parameters, their values are ignored. The default values are taken from the function implementation. The number of mandatory and optional parameters in forward declaration and implementation must match.
Function References
Function references allow to change the function called in an expression during the execution of a script: when a function reference is assigned to a variable or a parameter, the function can be called via the variable. The reference of a function is obtained by prefixing it with an ampersand character &:
f=&lower; // f now references the lower function
print f("Hello") // a call to lower
→ hello
f=&upper; // f now references the upper function
print f("Hello") // a call to upper
→ HELLO
|
Function references are often used to pass a function as a parameter to another function: the function integ approximates the integral of f from a to b:
function integ(f, a, b, n=100)
s=(f(a)+f(b))/2; h=(b-a)/n;
for i=1 to n-1 do
s+=f(a+i*h)
end;
return s*h
end
function inv(x) return 1/x end
print integ(&inv, 1, 2)
→ 0.6931534305
print integ(&math.sin, 0, math.pi/2)
→ 0.9999794382
print integ(&math.sin, 0, math.pi/2, 10000)
→ 0.9999999979
|
| | |
FunctionDeclaration := function Identifier FunctionBody .
FunctionBody := '(' [ParameterList] ')' OptionalType
( forward | {FunctionOption} StatementList end ) .
ParameterList := (MandatoryParameter {',' MandatoryParameter} |
OptionalParameter) {',' OptionalParameter} .
MandatoryParameter := VariableDeclaration .
OptionalParameter := VariableDeclaration '=' Expression .
FunctionOption := '/' OptionName ':' ParameterName .
OptionName := IdentifierChar | Digit .
ParameterName := Identifier .
ActualParameterList := Expression {',' Expression} .
FunctionCall :=
([ModulePrefix] Identifier '(' [ActualParameterList] ')'
{ Selector } [ InstanceFunctionReference ] .
IndirectFunctionCall :=
Designator '(' [ActualParameterList] ')'
{ Selector } [ InstanceFunctionReference ] .
|
|
Next: Modules© 2004-2011 airbit AG, CH-8008 Zürich
Document AB-M-REF-887