Control flow
AEL, the Agent Engineering Language, will have four ways to direct control: if, while, match and return. Each will be a statement, and the check will make sure that every path through a function ends the way its type says.
Status
Planned for AEL Beta 0.0.1. AEL is not available yet.
if and else
fn shipping(weight: u32, express: bool) -> u32 {
if express {
return 20;
} else {
if weight > 1_000 {
return 12;
}
}
return 5;
}
- The condition will have to be a
bool. An integer, text orOptionwill never be a condition. - The condition will need no parentheses; the blocks will always need braces.
elsewill take a block. To test a further condition, put anifinside that block, as above.- Only the chosen block will run.
while
fn sum_to(limit: u64) -> u64 {
let mut total: u64 = 0;
let mut n: u64 = 1;
while n <= limit {
total = total + n;
n = n + 1;
}
return total;
}
- The condition will be checked before every pass, including the first, so the body may run zero times.
- There will be no
breakorcontinue. End a loop through its condition, or leave the function withreturn.
match
match will compare one value against patterns, in order, and run the block of the first that fits.
enum Reply {
Empty,
Text(Str<200>),
Code(u16, Str<40>),
}
fn status(reply: Reply) -> u16 {
match reply {
Reply::Empty => { return 204; }
Reply::Code(code, _) => { return code; }
_ => { return 200; }
}
}
- The value will be evaluated once.
- The patterns will have to cover every possible value, and none may repeat another. A pattern after
_could never be reached, so it will be refused. - An enum will need every variant, or
_. Aboolwill needtrueandfalse, or_. Integer patterns, such as0or-1, will need a final_. - You will be able to bind a variant's values to names, as
codeabove, or skip them with_. Binding a value will move it out of the matched value; see Ownership. - Each arm will be a block. Its names will be visible only inside it.
- Patterns will be the wildcard,
trueandfalse, integers and enum variants. Structs, text, lists and references will be inspected with ordinary code instead, and a pattern will not be able to carry an extra condition.
Option and Result will be enums, so match will be how you handle them:
fn port_or_default(configured: Option<u16>) -> u16 {
match configured {
Option::Some(port) => { return port; }
Option::None => { return 8080; }
}
}
return
return value;will leave the function with a value of exactly its result type.- A function that returns unit will be able to write
return;, or simply reach the end of its body. - Every path through a function with a result will have to end in a
return. The check will count awhileloop as possibly running zero times, so areturnthat appears only inside a loop is not enough: add one after the loop.
Statements, not expressions
if and match will not produce values, and a block will not produce the value of its last line. To choose a value, give a binding its value in every branch:
fn fee(member: bool) -> u32 {
let amount: u32;
if member {
amount = 0;
} else {
amount = 3;
}
return amount;
}
The check will make sure that amount has a value on every path before it is read. Ownership describes the rule.
Loops and waiting
On a microcontroller, one handler will run at a time, until it waits for something. A loop that never waits will keep every other handler waiting, so keep the work between waits bounded. Concurrency describes scheduling.