Generator functions are a syntax of functions that construct Generator objects. Rather than manually calling the newGenerator.<T>() function (see #80), we can write a function with a special syntax to construct a Generator and specify its yielded values.
Countdown example calling constructing function:
let countdown: Generator.<int> = newGenerator.<int>((yielder, returner, counter) {
if counter == 0 then {
yielder.(3);
} else if counter == 1 then {
yielder.(2);
} else if counter == 2 then {
yielder.(1);
} else {
returner.();
};
});
Same example using generator function syntax:
func gen countdownFactory(): int {
yield 3;
yield 2;
yield 1;
}
countdownFactory; %: gen () => int
let countdown: Generator.<int> = countdownFactory.();
Generator functions require the gen keyword in the header. Rather than return statements (which are not allowed), generator functions may contain yield statements, and they can have more than one. Each time “next” (++) is performed, the function resumes execution until the next yield statement (or until the function returns). The “return type” of the function is written as the type of yielded values. The function implicitly returns type Generator.<T>.
Type Signatures
The type of a generator function has syntax gen (‹params›) => ‹yield›, where ‹params› are the parameter types and ‹yield› is the type of value yielded. It’s equivalent to the type signature (‹params›) => Generator.<‹yield›>.
Generator Lambdas
Generator functions can be function expressions (“lambdas”). Generator lambdas are expressions and can be passed around as such.
let multOf: gen (int) => int = gen (base: int): int {
for i from 1 to 0 do { % infinite loop
yield i * base;
};
};
Generator lambdas cannot have implicit returns. It’s a syntax error to write gen () => 42 as an expression. (It is valid as a type signature though: a generator function that yields values of type 42.)
Generator function syntax and
yield
statements.Discussion
Generator Function Declarations
Generator functions are a syntax of functions that construct
Generator
objects. Rather than manually calling thenewGenerator.<T>()
function (see #80), we can write a function with a special syntax to construct a Generator and specify its yielded values.Countdown example calling constructing function:
Same example using generator function syntax:
Usage:
Generator functions require the
gen
keyword in the header. Rather thanreturn
statements (which are not allowed), generator functions may containyield
statements, and they can have more than one. Each time “next” (++
) is performed, the function resumes execution until the nextyield
statement (or until the function returns). The “return type” of the function is written as the type of yielded values. The function implicitly returns typeGenerator.<T>
.Type Signatures
The type of a generator function has syntax
gen (‹params›) => ‹yield›
, where ‹params› are the parameter types and ‹yield› is the type of value yielded. It’s equivalent to the type signature(‹params›) => Generator.<‹yield›>
.Generator Lambdas
Generator functions can be function expressions (“lambdas”). Generator lambdas are expressions and can be passed around as such.
Generator lambdas cannot have implicit returns. It’s a syntax error to write
gen () => 42
as an expression. (It is valid as a type signature though: a generator function that yields values of type42
.)Specification
Lexicon & Syntax