Function definition - Palamecia/mint GitHub Wiki

Functions allow you to create a reusable and parameterizable part of the script. They are introduced by the def keyword that can be followed by:

A function always creates a block that will be executed when the function is called. When the function is called, a new context is created, and a result is always returned.

Note

A symbol name can be added before the call parameter list to automatically store the function in a global variable. This variable will also have a constant reference to avoid function redefinition but not a constant value to allow multiple signatures.

Example:

def func {} // create the global func function

Context

When a symbol name is used, a variable is created. This variable is associated with a context. When a function is called, a new context is created. This context is then empty unless a capture parameter list is used. This prevents changing the value of a variable of the caller context if a variable with the same name is used in the function.

When the function call is finished, the previous context is restored, and the script can continue as if no context change was made.

Capture parameter list

The capture parameter list allows you to store variables of the context where the function is defined in the context of the function. It starts with a [ and ends with a ] and contains a list of symbol name to capture separated by , or the ... operator to store the whole context.

Example:

a = b = c = 0

def [a, b] {} // function context includes variables a and b

def [...] {}  // function context includes variables a, b and c

Variables added to the capture parameter list are shared between the definition context and the function context. Modifying a variable in the function alters the corresponding variable in the definition context.

Example:

a = 0
def [a] { ++a } ()
a // gives 1

Important

The definition context of a function may differ from the caller context. Captured variables originate from the definition context, not the caller context.

Example:

a = 5
f = def {
    a = 0
    return def [a] { return ++a }
}
f()() // gives 1

A capture parameter can alias the result of an expression at function definition time using the = operator.

Example:

s = 'only need this in a string'

def [c = s[9..13]] {} // function context includes variable c initialized to 'this'

Tip

The alias capture mechanism can also create global variables at the function scope.

Example:

def [g_lib = lib('my-lib')] func(a) {
    return g_lib.call('func', a)
}

Call parameter list

The call parameter list allows you to define variables that must be initialized when the function is called. It starts with a ( and ends with a ) and contains a list of symbol name to use separated by , that can end with the ... operator to allow extra parameter initialization.

Example:

def (a, b) {}       // the a and b variables must be initialized at function call

def (a, b, ...) {}  // the a and b variables must be initialized at function call
                    // and other values can be initialized too

A function can store several blocks of script while a different call parameter list is associated with it. A call parameter list is different if the number of call arguments given is different and if extra parameters are allowed or not. To add a block of script to a function, the + operator can be used on two functions.

Example:

def (a, b) {} + def (a, b, c) {}  // create a function with two associated blocks

def (a) {} + def (a, ...) {}      // create a function with two associated blocks

A symbol name can use an access modifier to change the attributes of the parameter variable (except for the global reference modifier). This allows preventing the copy of a constant value when passed to a constant parameter.

Example:

def (a, %b) {} // the b parameter can take a constant value without a copy

A symbol name can be followed by the = operator to add a default value to the parameter. This allows calling the function without initializing this parameter. For function call, this is like creating a new block of script where the variable is initialized inside the block.

Example:

def (a, b = 0) {} // create a function with virtually two associated blocks

Important

Only the last parameters of the list can take a default value. Once a parameter uses this mechanism, all the following parameters must use it too.

If the list of parameters ends with the ... operator, extra values can be initialized at function call. All those extra values are stored in an iterator associated with the va_args variable.

Example:

def printf(format, ...) {
    print { format % va_args }
}

Result

All functions give a result when called. By default, the none value is returned when the end of the block is reached. This result can be used by the caller.

A custom result value can be used with the return keyword followed by an expression. The result of the expression is then used as the result of the function call.

Example:

sum = def (a, b) {
    return a + b  // return the sum of a and b
}

Important

The return keyword also forces the call to return immediately. All instructions of the function after a reached return will not be executed.

An iterator can also be generated with the yield keyword followed by an expression. The result of the expression is then used as an element of the iterator. When the yield keyword is used, the execution is then temporarily passed to the caller to allow it to use the generated value. The execution returns to the function when the next element of the iterator is requested. This is useful when the computation of a single element of the result takes a lot of time or memory and not all values are needed.

Example:

makeList = def (from, to) {
    value = doSomeBigComputation(from)
    while value != to {
        yield value
        value = doSomeBigComputation(value)
    }
}

Important

Functions that use the yield keyword are called generator functions. This kind of function always returns an iterator even if the yield expression was never reached.

Call

A function call is made using the function call operator on a function instance.

Example:

def {} ()  // call an in-line function

def func {}
func()    // call the function referenced by func

The corresponding block of script is selected depending on the number of call arguments given.

Example:

func = def(a) {
   return a
}

func += def(a, b) {
   return a * b
}

func(10)      // gives 10
func(10, 10)  // gives 100

The unpack operator can also be used in a function call to expand each element of a container as an individual parameter.

Example:

func = def(a) {
   return a
}

func += def(a, b) {
   return a * b
}

func(*[10])      // gives 10
func(*[10, 10])  // gives 100

If the function takes at least one parameter, the function call can be made using the . operator of an object. The object will then be used as the first parameter of the function. The function must be defined in the global package or in a package containing the object type for user defined types

Example:

def doSum(object) {
    for item in object {
        if defined result {
            result += item
        } else {
            result = item
        }
    }
    return result
}

[1, 2, 3].doSum()       // gives 6
(5).doSum()             // gives 5
('f', 'o', 'o').doSum() // gives 'foo'

Warning

For numeric constants, the '()' operator must be used to avoid confusion between the . operator and the decimal separator.


« Control structures   User-defined types »
⚠️ **GitHub.com Fallback** ⚠️