Pyro

A dynamically-typed, garbage-collected scripting language.

Version 0.17.7

Functions


Function Definitions

Function definitions look like this:

def add(a, b) {
    return a + b;
}

assert add(1, 2) == 3;

If you don't explicitly return a value from a function, its return value is null.

Functions As Values

Functions are first-class citizens in Pyro, meaning you can assign them to variables and pass them around just like any other value, e.g.

def add(a, b) {
    return a + b;
}

var foo = add;
assert foo(3, 4) == 7;

Anonymous Functions

You can declare and use functions anonymously, e.g.

var add = def(a, b) {
    return a + b;
};

assert add(5, 6) == 11;

Closures

Pyro has full support for closures. An inner function declared inside an outer function can capture the outer function's local variables, including its parameters, e.g.

def make_adder(increment) {
    def adder(num) {
        return num + increment;
    }
    return adder;
}

var adds_one = make_adder(1);
assert adds_one(0) == 1;
assert adds_one(1) == 2;

var adds_two = make_adder(2);
assert adds_two(0) == 2;
assert adds_two(1) == 3;

Functions can also capture global variables, e.g.

var suffix = "_end";

def make_closure() {
    return def(string) {
        return string + suffix;
    };
}

var adds_suffix = make_closure();
assert adds_suffix("foo") == "foo_end";

suffix = "_new_end";
assert adds_suffix("bar") == "bar_new_end";

Default Argument Values

You can specify default values for trailing arguments, e.g.

def func(arg1, arg2 = "foo", arg3 = "bar") {
    return $tup(arg1, arg2, arg3);
}

assert func(1) == $tup(1, "foo", "bar");
assert func(1, 2) == $tup(1, 2, "bar");
assert func(1, 2, 3) == $tup(1, 2, 3);

A default argument value must be a simple literal — one of i64, f64, rune, str, bool, or null.

Variadic Functions

A variadic function is a function that accepts a variable number of arguments.

To define a variadic function, prefix its final parameter with a *, e.g.

def vfunc(arg1, arg2, *args) {
    return args;
}

assert vfunc(1, 2) == $tup();
assert vfunc(1, 2, 3) == $tup(3);
assert vfunc(1, 2, 3, 4) == $tup(3, 4);

The variadic arguments are available inside the function as a tuple.

Unpacking Arguments

When calling a function, you can 'unpack' the final argument using a * if it's a tuple or vector, e.g.

var numbers = [1, 2, 3];

var sum1 = add(*numbers);           # add(1, 2, 3)
var sum2 = add(123, 456, *numbers); # add(123, 456, 1, 2, 3)

Trailing Commas

Trailing commas are allowed in function definitions, e.g.

def add_args(
    arg1,
    arg2,
    arg3,
) {
    return arg1 + arg2 + arg3;
}

Trailing commas are also allowed in function calls, e.g

var result = add_args(
    "foo",
    "bar",
    "baz",
);

assert result == "foobarbaz";

Multiple Return Values

Functions can return multiple values, e.g.

def get_values() {
    return 123, 456;
}

assert get_values() == $tup(123, 456);

This is syntactic sugar for returning a tuple — i.e. it's equivalent to:

def get_values() {
    return $tup(123, 456);
}

assert get_values() == $tup(123, 456);

You can unpack a tuple returned by a function in a var declaration using (), e.g.

var (foo, bar) = get_values();
assert foo == 123;
assert bar == 456;