6 Procedures and control flow
A workflow contains commands and named procedures. Commands run in written order; a to declaration makes a procedure available but does not run it. Definitions may appear after calls. The Syntax page gives the naming convention and file-level rules.
6.1 Procedures, calls, and results
Form | Meaning |
to name :input ... [ commands ] | Define a procedure with zero or more inputs |
do name value ... | Call a procedure for its actions |
do name value ... as result | Call a procedure and name its returned value |
name = value | Create or update a local named value |
name += [field = value ...] | Update or add fields on an existing record |
name += number | Add a number to an existing numeric value |
name += value | Append one item when name holds a list |
output value | Return a value from inside a procedure |
print value | Display a value on a line |
do estimate-period 20 10 as period |
print period |
|
to estimate-period :seconds :swings [ |
about "Estimate one period from a duration and swing count." |
output :seconds / :swings |
] |
Inputs are declared with : in the to header and referenced with : inside that procedure, including in calls it makes. as period names the result in the caller. A call using as needs an output in its procedure. Procedure names must be distinct; recursive calls are rejected. print is a teaching and display action, not a scientific observation or evidence record.
An optional about "Markdown text" belongs first inside a procedure’s opening bracket. It describes the reusable method and remains available through imports and includes. It does not run as a command or replace its input and result declarations. See Describe a workflow, stage, or procedure.
6.2 Local values and scope
name = value creates a named value or updates a visible value previously created by assignment. The procedure can read its declared inputs, but does not see the caller’s local names. A nested block can read names from its parent and update a visible assigned name. A name first introduced inside do [ ... ], a loop, or a branch remains inside that block; its parent and sibling blocks cannot read it. There are no global variable declarations.
At command position, name = value is assignment. A dotted target such as trial.clock.time = "12:00" updates nested content. Inside a record or trial.[field = value], field = value names a field; inside an interface it supplies a field default. name += [field = value] updates or adds record fields; name.field += number adds to an existing numeric field. When the left side is a list, += appends one item. These updates require an existing value on the left. In a condition such as if count == 10 [ ... ], == compares values. A comparison can be passed directly to a procedure, as in do check count == 10. Parentheses remain available to group an expression.
Compact
attempts = 0 |
do [ |
attempts += 1 |
note = "inside this block" |
] |
print attempts |
Verbose
set attempts to 0 |
do [ |
update attempts with 1 |
set note to "inside this block" |
] |
print attempts |
Here attempts becomes 1; note is local to the do block. Procedure inputs, as results, and for each iteration names cannot be changed by assignment. An as result must introduce a new name in its current scope. A to procedure sees its own inputs, not values from the surrounding workflow. Stages are labels, not variable scopes.
6.3 Sequence and stage headers
do [ commands ] runs a block once, in order. stage name labels following commands until another stage at the same nesting level or the block’s end. A stage is a checkpoint for the written method; it is neither a procedure nor a command to call. Stage names must be distinct across the assembled workflow, including its procedures. A procedure defined between stage headers remains available throughout its enclosing workflow.
Compact
workflow "Review a timing plan" |
stage Prepare |
do make-plan as plan |
stage Review |
print plan |
to make-plan [output "Time ten swings as the swing gets smaller."] |
Verbose
workflow "Review a timing plan" |
start stage Prepare |
do make-plan as plan |
start stage Review |
print plan |
to make-plan [output "Time ten swings as the swing gets smaller."] |
The second stage can use plan because a stage does not create a new scope. do Review would call a procedure named Review; it does not call the stage. Stages and state explains the paired form that declares a stage’s incoming and outgoing state.
6.4 Conditions and repetition
Each condition is a Boolean expression or comparison from Values and expressions. An unknown or nonboolean condition stops execution instead of choosing a branch. Square brackets delimit each command block.
Form | Meaning |
if condition [ ... ] else if condition [ ... ] else [ ... ] | Run the first true branch; the final else is optional |
repeat count [ ... ] | Run a block a fixed number of times |
for each name in sequence [ ... ] | Run once per item in an ordered list |
while condition [ ... ] | Test before each iteration |
repeat [ ... ] until condition | Run once, then test after each iteration |
repeat needs a nonnegative integer count. for each needs an ordered list; its iteration name exists only inside that iteration and cannot be updated by assignment. A repeat ... until condition may read a name introduced in its body. while and repeat ... until stop with an error after 10,000 iterations if they have not terminated.
Compact
lengths = range 0.25 to 1 step 0.25 |
for each length in lengths [ |
if length > 0.5 [print length] |
] |
|
done = false |
repeat [ |
done = true |
] until done |
Verbose
set lengths to range from 0.25 to 1 with step 0.25 |
for each length in lengths [ |
if length is greater than 0.5 then [print length] |
] |
|
set done to false |
repeat [ |
set done to true |
] until done |