More on SPL Functions

 

There are several methods of creating user defined functions. Single line functions can be defined directly from the command line with the #deffun directive :

 

#deffun name(arg1, arg2, arg3, ..., argN) statement

 

where name is a string that identifies the function and argN is any number of arguments to the function. The body of the function is specified by statement and typically consists of one or more expressions that incorporate the function arguments. For example:

 

#deffun normal(s) return(s/max(s))

 

A function is invoked by referring to the function name and appropriate arguments.

 

normal(W1)

 

If a function does not accept arguments, the argument list is omitted.

 

#deffun minmax max-min

 

SPL function names are not case sensitive. Unlike C/C++, the return type of the function is not explicitly specified.

 

The function delfun(minmax) deletes the function minmax from the current session.

The command clear minmax also deletes function minmax.

 

Multiline functions are defined in standard text files. The name of the file is typically the same name as the main function with extension .spl. The function body must be enclosed in braces, { }. The argument list, if any, must be enclosed in parentheses, ( ) and immediately follow the function name.

 

/* normal.spl */

normal(s)

{

    return(s / max(s));

}

 

Here's an example of a function that creates a series consisting of the Fibonacci numbers:

 

// Fibonacci numbers returned as series

fib(x)

{

    local a, b, c, j, sig[];

 

    a = 0;

    b = 1;

    j = 1;

 

    while (b < x)

    {

        c = b;

        b = a + b;

        a = c;

        sig[j] = a;

        j++;

    } 

 

    return(sig)

}

 

A more compact example of generating the Fibonacci numbers:

 

// compact Fibonacci

fib2(n)

{

    local j = 1, f = {1, 1};

 

    while (f[j] + f[j+1] < n)

    {

        f[j+2] = f[j] + f[j+1];

        j++;

    }

 

    return(f);

}

 

In this example, the local variable j is initialized to 1 and the first two elements of array f are initialized to 1.

 

And finally, for n up to 70, a very fast and clean implementation derived from a clever formula:

 

// fast Fibonacci

fastfib(n)

{

    local a, b, c, f; 

    

    a = sqrt(5)

    b = (1 + a) / 2

    c = -1 / b; 

    

    f = (b^n c^n) / a; 

    

    return(f)

}

 

This version avoids looping and has the advantage of processing both scalar and series inputs.

 

a = fastfib(6)

b = fastfib(1..6)

 

a == 8

b == {1, 1, 2, 3, 5, 8}

 

The preceding iteration of the Fibonacci routine demonstrates one very important maxim for any sort of programming: first make it work, then make it work fast. However, don't waste time improving the implementation of a poor algorithm, rather spend the time searching for a better algorithm. That’s where the greatest speed and efficiency gains are to be found.