1 (true) or 0 (false); see Operators and precedence.
If [if]
comparison; returns true_statement if it is true, otherwise false_statement. Any expression can appear in any position, and if calls can be nested on either branch.
comparison uses one of the comparison operators:
Use
== (comparison) inside conditions, not = (assignment). See Operators and precedence.if returns whichever branch it takes, with that branch’s unit — nothing converts one branch to match the other:
Combining conditions
Combine comparisons with&& (and), || (or), and ! (not). A good rule of thumb is to write the condition the way you would say it out loud.
>, <) and inclusive (>=, <=) comparisons differ exactly at the boundary value — choose deliberately.
Nested calls cover more than two outcomes — here, a different result for “more than 10 over,” “1–10 over,” and “not over”:
Choose [choose]
index (starting with 1) — a shorthand for a chain of if statements. index must be a whole number from 1 to N, an expression that evaluates to a whole number, or a Parameter out of range error is returned.
if, choose returns the expression it lands on, carrying that expression’s unit, and the alternatives are not compared with one another.
Loop [loop]
expression from from to to, building a table with one row per iteration. It counts by 1 unless you pass a step, and ends when the index passes to. Two special variables are available inside the expression:
index— the current value of the loop counter. It starts atfromand advances bystep, so the defaultloop(1; n)runs1, 2, … nwhileloop(1; 5; 2)runs1, 3, 5.last— the value from the previous iteration (0on the first).
index or last is ignored in favor of the loop’s own.
Direction. With no step, the loop counts by 1 toward to — downward when to is below from. An explicit step must point toward to, or an input.out_of_range error is returned: loop(5; 1; -2) runs, loop(5; 1; 1) does not. A fractional step is allowed; the last row is the final index that has not passed to, so loop(5; 1; -1.1) runs 5, 3.9, 2.8, 1.7.
Looping over a unit range
from, to, and step each take a unit value as readily as a scalar, and index carries the unit into the expression. All of them must share a dimension: mixing a bare scalar with a unit value returns an input.incompatible_units error. A bound of 0 is the exception — from or to may be a bare 0 alongside unit-bearing arguments, and takes its unit from them.
index is expressed in the unit of the increment — the step’s unit when you pass one, otherwise the unit of the first bound that carries one. Bounds given in other units are converted to it, so a loop from 1mo to 5yr runs sixty monthly rows.
A mo is a fixed 30.4375 days and a yr a fixed 365.25 days, so a range in months rarely comes out even in another unit — 12 months is 52.18 weeks, not 52. Every mo step is that same fixed length, which is not what a calendar month does. To build a payment schedule or a monthly projection, loop over a plain count and move the date with adjdate.
Building a series
Two loop patterns recur when projecting values over time. Compound growth — a value that grows at a fixed rate each period from a first-period base:index - 1 exponent holds the first period at base (^ 0 is 1), and ceil guards against a fractional periods. The result is one row per period.
Running total — a cumulative sum across an existing table, with last as the accumulator:
item(result; length(result)) — is the all-up total. See item and length in Table functions.
