4. Expressions and control flow
An expression produces a value or performs an action. Capy evaluates listed expressions from left to right.
Calculate a value
function RENDER(request : dval) {
var price := 6
var quantity := 2
var total := price * quantity
print(total, "\n")
}
Output
12
* runs before + and -. Parentheses make the intended order explicit.
Declare and assign locals
:= declares a local and infers its type. = replaces its value:
function RENDER(request : dval) {
var count := 1
count = count + 1
print(count, "\n")
}
A local exists until the end of its block. An inner block can declare a new local with the same name without changing the outer local.
Conditions
Use if to select code:
function RENDER(request : dval) {
var total := 12
if total > 10 {
print("large\n")
} else {
print("small\n")
}
}
Capy evaluates each condition as bool(condition). A condition can use any value with a bool constructor. A string has no bool constructor and cannot be a condition.
An if with else can also produce a value:
function RENDER(request : dval) {
var total := 12
var label := if total > 10 {
-> "large"
} else {
-> "small"
}
print(label, "\n")
}
Each reachable branch that produces a value must produce the same type. A branch that returns or traps does not produce a value.
Loops
A while loop repeats while its condition is true:
function RENDER(request : dval) {
var index := 0
while index < 3 {
print(index, "\n")
index = index + 1
}
}
A for loop reads a half-open s64 range, an array, or a dval map or list:
function RENDER(request : dval) {
for number := 1..4 {
print(number, "\n")
}
}
The range is half-open. 1..4 contains 1, 2, and 3. A range permits one loop value only.
Optional metadata follows the value:
function show(names : [string], profile : dval) {
for name, index := names { print(index, ": ", name, "\n") }
for item, key := profile { print(key, ": ", item, "\n") }
}
function RENDER(request : dval) {
show(["Ada"], {role: "admin"})
}
An array index has type s64. A dval key has type string. dval list keys are decimal strings. Structs are not iterable. The old = and in forms are invalid.
Array and dval loops recheck the current count before each iteration. A loop can visit items added while it runs. Shrinkage cannot cause an invalid access. dval loop items are copies. An array loop retains its current managed item while the body runs.
Use break to leave the nearest loop. Use continue to start its next iteration.
Blocks
A block yields a value when its final reachable item starts with ->:
function RENDER(request : dval) {
var total := {
var subtotal := 10
-> subtotal + 2
}
print(total, "\n")
}
This makes total equal to 12. A block can keep temporary locals close to the calculation that uses them.