Closures in UnrealScript

class Closures extends Object;

// This function intSeq returns another function, which
// we define anonymously in the body of intSeq. The
// returned function closes over the variable i to
// form a closure.
function delegate<int> intSeq()
{
    local int i;
    return delegate<int>()
    {
        i++;
        return i;
    };
}

// The main function in UnrealScript is typically called DefaultProperties
function DefaultProperties()
{
    local delegate<int> nextInt;
    local delegate<int> newInts;
    
    // We call intSeq, assigning the result (a function)
    // to nextInt. This function value captures its
    // own i value, which will be updated each time
    // we call nextInt.
    nextInt = intSeq();
    
    // See the effect of the closure by calling nextInt
    // a few times.
    `log("" $ nextInt());
    `log("" $ nextInt());
    `log("" $ nextInt());
    
    // To confirm that the state is unique to that
    // particular function, create and test a new one.
    newInts = intSeq();
    `log("" $ newInts());
}

UnrealScript supports anonymous functions and closures, although the syntax and implementation differ from many other languages. In this example, we’ve translated the concept of closures to UnrealScript.

The intSeq function returns a delegate (UnrealScript’s equivalent of a function pointer) that increments and returns an integer. This delegate forms a closure over the local variable i.

In the DefaultProperties function (which serves as our main function in this context), we create an instance of the closure by calling intSeq() and assigning it to nextInt. We then call this delegate multiple times to demonstrate that it maintains its own state.

To show that each closure has its own independent state, we create a new closure newInts and call it once.

Note that UnrealScript doesn’t have a direct equivalent to Go’s fmt.Println(), so we use the log statement (represented by the backtick syntax `log()) to output to the console.

This example demonstrates how UnrealScript can use delegates to achieve functionality similar to closures in other languages, allowing for the creation of functions that maintain their own state between calls.