Effect rows
The with { ... } clause is the complete list of what a function does beyond computing its result: which capabilities it uses, and which effects it can raise. The row is a set, sorted and deduplicated. ? propagates one kind of effect, err: T, and nothing else.
function load(rfs: ReadOnlyFilesystem, path: String, allocator: Allocator) -> Config
with {rfs, allocator, err: fs.FsError, err: str.ParseFloatError}
{
let text = fs.read_to_string(rfs, path, allocator)?
return parse_config(text)?
}The pure effects are err: T, panic, yield: T, cancellation, divergence, and nondet. Graded effects add a static bound, checked at compile time: alloc(bytes <= 4096), io(calls <= 1), time(ops <= N). A handler removes an effect from the row:
handle err: fs.FsError as e -> default_for(e) {
read_config(rfs, path, allocator)?
}