Every step has a result, and that result carries a value. A value can be the response from another procedure, the return from a function call, or a literal from the input document itself.

The result of a step is the last thing that happens in it. If there's nothing else saying what the value is, then the result of the step is the unit type, Unitus, written (). It's what we use to say "this step is done, but it didn't have any value in particular."

Binding a return value

A prose step, where the task to be performed is described in text, can indicate that a result is to be recorded with an actual value. This is done by binding the step to a variable:

    3.  Annnounce last drinks. Collect orders from the patrons ~ orders

We haven't said anything particular about what shape {orders} has to be, and that's fine. You can just write down people's orders, but the value you write down is captured in the variable.

This works in code blocks, too

    3.  Annnounce last drinks
        {
            say("Last orders, please")
            take("Collect orders from the patrons") ~ orders
        }

In both cases, the result of the step is still Unitus. This is because the last thing in the step is a binding, not a value. We haven't returned anything. If you actually want to capture the value and return it as the result, you need to say so:

    3.  Annnounce last drinks
        {
            say("Last orders, please")
            take("Collect orders from the patrons") ~ orders
            orders
        }

You typically would not need to do this, however, because most of the time the next thing will be to use the variable:

    4.  Serve the drinks
        @barman
            a.  <serve>(orders)

Thus we see that binding works on plain prose steps, procedure invocations, and function calls.

Multiple returns

Some procedures and functions return more than one value. Let's say the procedure to serve the order returns the drinks, and the bill to be paid:

serve :: Orders -> Drinks, Bill

We could invoke this and bind the result for use in subsequent steps:

    4.  Serve the drinks
        @barman
            a.  <serve>(orders) ~ (drinks, bill)

Although as seen here procedure signatures can have "naked" tuples omitting the parenthesis around the types, when binding a tuple return you need to include parenthesis so the compiler can figure out which are the variables being bound, and what might be prose that continues the step — though as we know, this is the last step before the end of the world, so chances are the bill is going to go unpaid.

© 2004-2026 Athae Eredh Siniath, and Others. Technique is open source and MIT licensed.