Skip to content

Functions

cyxigo edited this page Jul 13, 2026 · 4 revisions

Introduction

In programming, a function is simply a reusable block of code. In Wi, functions are first-class citizens, meaning they can be stored in variables, passed as arguments to other functions, and returned from other functions.

Function definition

In Wi, functions are expressions, so to define a function you need to declare a variable and define it with function expression:

var f = function() {
};

Let's analyze what is what here.

  • (): this is the function's parameter list. A parameter is an input to a function. In this example f has no parameters. In this one, however:
var f = function(x) {
};

It has a parameter called x.

  • { and }: this is the function body. It is defined by a block and has its own scope. Parameters are locals within that scope.

Calling functions

Executing a function is called calling it. To call a function, we use the call operator () which we discussed earlier. In case you forgot:

Call operator () is used to call functions. It accepts arguments separated by ,

Arguments are values that you pass into the function parameters.

For example, our good old function f. To call it, we need to pass a value to the parameter x:

var f = function(x) {
};

f(10);

Here, 10 is the argument, x is the parameter. We pass 10 into x. If you don't pass enough arguments into a function, you will cause a runtime error:

var f = function(x) {
};

f();
runtime error: expected 1 arguments but got 0
   --> file.wi:4 in main function

A technical term for a function's accepted parameter count is arity.

Returning values

Every function returns some value. Think of returning a value as the answer. You called a function, it answered with a value. Even if you don't specify one, Wi implicitly returns null from every function (the function has to answer our call). So if we were to print out the f example:

var f = function(x) {
};

print(f(10));

We would see:

null

But we have a handy return statement, which accepts an expression to make our answer different:

var f = function(x) {
    return x;
};

print(f(10));

Now when we call our f, it answers with x, its parameter, and since we passed 10 into x we see:

10

return statement can also be used to stop some code from executing, for example:

var f = function(x) {
    if (x == 4) {
        return;
    }

    print(x);
};

f(4);
f(10);

In this example, if the passed argument is 4, we won't print it. This program will output:

10

return without an expression will return null.

Recursion

A function can call itself. This is called recursion.

Let's define a function to calculate the factorial of a number n using recursion:

var factorial = function(n) {
    if (n <= 1) {
        return 1;
    }

    return n * factorial(n - 1);
};

print(factorial(5)); // 120

Let's analyze what's happening here.

When we call factorial(5), it checks if n is less than or equal to 1. This is a safeguard here to prevent infinite recursion - if we didn't have it, the function would call itself forever, eventually causing a stack overflow error. Since 5 is not <= 1, it returns 5 * factorial(4).

  • factorial(4) returns 4 * factorial(3).
  • factorial(3) returns 3 * factorial(2).
  • factorial(2) returns 2 * factorial(1).
  • factorial(1) hits the safeguard and returns 1. Then the results "unwind":
factorial(5) = 5 * 4 * 3 * 2 * 1 = 120

Recursion has limits. If you call a function too many times without returning, you'll cause a stack overflow:

var infinite = function() {
    infinite();
};

infinite();

The error message isn't pretty, but you'll definitely notice it.

Clone this wiki locally