Generator Blocks

As discussed in the coroutine section, the yielded value must be inspected by a special syntactic structure. Second class borrows prevent types like Opt[&T] from being yielded, so in this example, GenOpt[&T] is used. This doesn’t store the borrow inside a type, but the generator is aare that there may not be a value associated with the generated value.

The iter block is used to inspect the different states of a generated value. A generator type will always yield a Generated type, mirroring the type of generator doing the yielding:

Generator Type

Generated Type

Gen[Yield, Send=Void]

Generated[Yield]

GenOpt[Yield, Send=Void]

GeneratedOpt[Yield]

GenRes[Yield, Err, Send=Void]

GeneratedRes[Yield, Err]

The GenOnce assumes type doesn’t have a mirroring Generated type, as it attempts to inspect a value directly.

Basic Branching

The structure of an iter block resembles a case-of block directly, with different branch patterns available, to inspect different generator states.

There are a total of four different states the at generated values can be in (some states are specific to certain GeneratedXXX types, enforced at compile time):

Present Value

If a value is present it is destructured by simply providing a variable name. The created variable will have a type that matches the Yield argument exactly, including the potential borrow convention. This is the most common case, and the syntax is as follows:

iter generated_value of
    variable { ... }

No Value Present

If an optional generator is used, it may yield a value that indicates that there is no value present. The underscore _ token is used to indicate that there is no value present, in the same way it is used to skip a value in standard destructuring. The syntax for this is as follows:

iter generated_value of
    _ { ... }

Error Present

If a fallible generator is used, it may yield an error value. The ! token, followed by a variable to bind the exception to, is used to indicate that an error is present. The created variable will have a type that matches the Err argument exactly. The syntax for this is as follows:

iter generated_value of
    !exception { ... }

Exhausted Generator

If a generator has exhausted all values, it can be indicated by using the !! token. This indicates that the generator has no more values to yield; either the end of the coroutine has been reached, or the coroutine has been explicitly terminated with an early ret, possibly conditional. The syntax for this is as follows:

iter generated_value of
    !! { ... }

Compatibility

Gen

For the standard generator block, the Generated[Yield] value can be in two states: either a value is present, or the generator has exhausted all values. The syntax for this is as follows:

iter generated_value of
    variable { ... }
    !! { ... }

GenOpt

For the optional generator block, the GeneratedOpt[Yield] value can be in three states: a value is present, no value is present, or the generator has exhausted all values. The syntax for this is as follows:

iter generated_value of
    variable { ... }
    _ { ... }
    !! { ... }

GenRes

For the fallible generator block, the GeneratedRes[Yield, Err] value can be in three states: a value is present, an error is present, or the generator has exhausted all values. The syntax for this is as follows:

iter generated_value of
    variable { ... }
    !exception { ... }
    !! { ... }