SPL functions

SPL functions are written directly in SPL, not natively in the languages C++ or Java.

Here is an example of a non-native function definition:
float64 toCelsius(float64 fahrenheit) {
  float64 freezing = 32f, ratio = 5f / 9f;
  return (fahrenheit - freezing) * ratio;
}
An SPL function definition consists of a head and a block:
functionDef      ::= functionHead blockStmt
functionHead     ::= functionModifier* type ID '(' functionFormal*, ')'
functionModifier ::= 'public' | 'stateful'
functionFormal   ::= 'mutable'?  type ID

The function head contains optional modifiers, the return type, identifier, and list of parameter definitions.

The modifiers stateful for functions and mutable for function parameters are described from the caller's perspective in Side-effects. From the perspective of the function body, they restrict what it can do: the body of function f1 can call only a stateful function f2 if f1 is declared stateful too, and the body of a function can modify only a function parameter if that parameter is declared mutable.

The modifier public for SPL functions makes the function visible from other namespaces. Without the modifier, SPL functions are private and only visible in their own namespace. Distinguishing public from private functions helps in large projects because internal helper functions do not become part of the public interface, and because access to stateful private functions is restricted to code that is aware of the invariants for the state.