Functions

Definition

A function call executes the function with a given set of parameter, then returns a value. Functions can return void. When calling a method, scalar types are passed by value, complex types are passed by reference. This means that if you pass an array to a function and modify it inside the function, you will have a modified array after the function call.

You define functions with the def keyword:

def function (scalar, complex){
  complex[0] = scalar
  scalar = 5
  return 42
}
 
def scalar = 10
def complex = array(10)
function(scalar, complex)
trace scalar // Will output 10, not 5 !
trace complex[0] // Will output 10

No type declaration is necessary. A function defined in a script or a module can take any local variable or document variable as an input. If the function is defined in a script, it can only be used by this script.

Method calls differ from C++/Java in the fact that calling the same method with different parameter types is allowed. For instance the function below would work for any type:

def identity(obj){
  return obj
}

You can define functions in two places :

  • Locally, inside a script.
  • Globally, inside a module.

Function Signature

Two functions are allowed to have the same signature only if you define them in different modules. In this case, you must use the fully qualified name that is composed of module_name and function_name, such as:

Module1.function(1, 2) + Module2.function(1, 2)

Function Overloading

You can overload a function by providing a definition with a different signature. In this case, you can add both the original and overloading functions in the same module. For example:

// define an initial function
def helloWorld(string1) {
  return string1;
}

// overload the initial helloWorld function
def helloWorld(string1, string2) {
  return string1 + string2;
}

Visibility

Function visibility is restricted and ruled by annotations:

  • Default: if no annotation is present, the function can only be used in its module.
  • @Protected: the function is visible in its whole library.
  • @Public: the function is visible everywhere.
//js
def f() {} //visible only in the module
 
@Protected
def g() {} //visible only in the library
 
@Public
def h() {} //visible everywhere

Function overriding

Module functions can be overridden for a specific script. Here are the conditions to override a function:

  • Initial function should be annotated with @AllowOverride and @Public annotations.
  • Overriding function should be annotated with @OverrideMethod annotation.

Functions can only be overridden in scripts. For example:

// In a module: 
@Public
@AllowOverride
def f() {
    //...
}
// In a script file: 
@OverrideMethod
def f() {
    //...
}
 
return f()

Function Pointers

FPP allows you to define variable of type pointer to functions. These variables are not represented into the GPU, since they are never transferred there, but you can use them as function arguments. Below you can find an example usage:

// Define your function
def square(x){
    return x * x
}
// Define the function that will call it
def apply(f, value){
    return f(value)
}
// Make the call
return apply(square, 5) // This will return 25

Note that the use of f in the apply function is tied to the square signature. Parameter carrying is not supported for the moment. If you require variable size input, passing an array of values as a single argument is recommend.