日本語

Functions

This section explains function definitions, calls, and advanced features in LuneScript.

Definition

Functions are defined using the fn keyword.

// No arguments, no return value
fn hello() {
    print( "Hello" );
}

// With arguments, with return value
fn add( val1: int, val2: int ): int {
    return val1 + val2;
}

Public Functions

To make a function public (accessible outside the module), use the pub keyword. Public functions can only be defined at the top-level (uppermost scope).

pub fn globalFunc() { print("global"); }

Multiple Returns

LuneScript can return multiple values at once.

fn div_mod( a: int, b: int ): int, int {
    return a / b, a % b;
}
let d, m = div_mod( 10, 3 );
print( d, m ); // 3, 1

Notes on Multiple Returns (Lua/LuneScript Specifications)

When passing a function call as an argument, all return values are expanded only if it is passed as the final argument.

fn func(): int, int { return 1, 2; }

print( func() );      // 1, 2 (All expanded)
print( func(), 10 );  // 1, 10 (The second return value is discarded!)
print( 0, func() );   // 0, 1, 2 (All expanded)

To prevent accidents where return values are unintentionally discarded, it is recommended to explicitly use ** when passing multiple values as arguments in LuneScript (this may become mandatory in the future).

fn func(): int, int { return 1, 2; }
fn func2( ... ) {}
func2( func()** ); // Explicitly pass all multiple values

Closures and Anonymous Functions

You can create unnamed functions (anonymous functions), assign them to variables, or pass them as function arguments.

fn run( cb: form ) {
    cb();
}
let val = 10;
run( fn() {
    print( val ); // Captures external variables (closure)
} );

Form (Function Type)

The form keyword is used to represent the type of a function. However, a simple form type is an overly broad type (essentially something like stem!) meaning "a function with arbitrary arguments and arbitrary return values".

To define a function type with a specific strict signature, use the form declaration.

// Define a function type 'IntFunc' that takes an int and returns an int
form IntFunc( val: int ): int;

fn exec( f: IntFunc, v: int ) {
    print( f( v ) );
}

exec( fn( v: int ): int { return v * 2; }, 10 ); // 20

Variable Arguments (Varargs)

You can define variable arguments using ....

fn dumps( ... ) {
    let list = [ ... ]; // Convert to list
    foreach val in list {
        print( val );
    }
}
dumps( 1, "test", true );

If you want to specify types, consider using Generics or design the function to receive a list.

Optional Arguments

Arguments of Nilable types can be omitted at the time of calling. If omitted, nil is passed.

fn opt( val: int! ): int {
    return unwrap val default 0;
}
print( opt( 10 ) ); // 10
print( opt() );     // 0 (val is nil)

You can use ## to explicitly indicate an omission (opt( ## )). This is to clarify in the code that the omission was intentional.