Blocks Given to a Call
● Beginner3 minBefore this: Break/Continue, trySpec 4.8
A few standard-library calls take a block after them, log.span("name") { … } and random.seeded(seed) { … }, and run it inside something they set up.
use std.log
type CartError = Empty
fn total(prices: [Int]) -> Int ! CartError {
log.span("checkout") {
if prices.is_empty() {
fail CartError.Empty
}
let sum = 0
for p in prices {
sum += p
}
sum
}
}
fn main() {
print(total([300, 450]) catch _ => -1)
print(total([]) catch _ => -1)
let checked = 0
for size in [5, 8, 12] {
log.span("check") {
checked += 1
if size > 6 {
break
}
}
}
print(checked)
}The program ran and printed:
kavach run block-given.kav
750-12
- The block is a plain block, not a lambda:
fail,try,return,breakandcontinueact as they would without the call. - It can change the variables around it:
checked += 1counts on the outside. - The expression's value is the block's value:
totalgives the sum. - What the call set up ends when the block ends, however it ends: by its value, an error, a
return, abreakor a panic. - The block starts on the same line as the call's
).
Which calls take one
Only standard-library functions that say so: log.span (see Logging) and random.seeded (see Random Numbers). One of them without its block is a compile error:
use std.log
fn main() {
log.span("checkout")
print("done")
}The compiler refused the program:
kavach run block-missing.kav
error: `log.span` runs a block: write it after the call, `log.span(name) { … }` (spec 4.8)A block after any other call is refused too, and the message names the calls that take one:
fn greet(name: String) -> String {
"hi {name}"
}
fn main() {
const text = greet("Asha") {
print("x")
}
print(text)
}The compiler refused the program:
kavach run block-other-call.kav
error: only `log.span(name)` and `random.seeded(seed)` take a block after them (spec 4.8): start the block on a new line, or call one of them