failable-in-closure
Translation status: हिन्दी reader-locale proof. Term names and code fences follow the hi pack; supporting prose may still be English.
A closure is its own frame: it neither inherits the enclosing function's ⇥ channel nor leaks one; a failable call inside a closure is handled inside the closure.
Syntax: (<T>) → <R> <name> ← <params> → <R> ∴ do { do { … risky(x) … } catch err { … } }
Category#
function
Related#
Examples#
radix/corpus/clausura/failable-in-closure.fab (canonical · concept)#
A closure is its own frame: it neither inherits the enclosing function's ⇥ channel nor leaks one; a failable call inside a closure is handled inside the closure.
# =============================================================================
# failable-in-closure — closures inside failable functions, failable calls inside closures
# =============================================================================
#
# What this teaches:
# • A closure's `return` returns a plain value of the closure, even when
# the enclosing function declares `⇥`: the error channel belongs to the
# function, not to the closures it creates.
# • A failable call inside a closure body needs a handler inside that body
# (`do { … } catch err { … }`); the handled failure becomes the closure's
# own value, and the enclosing function never sees it.
#
# Common mistakes:
# • Calling a failable function in a closure body with no handler and no
# `⇥` of its own — rejected by the analyzer.
#
# See also: समापन, ⇥, करो, पकड़ो
# =============================================================================
# failable-in-closure — closures keep their own frame
#
# EXPECTED OUTPUT:
# failable-in-closure.expected — one line per call; the handled failures print -1.
fn risky(int n) → int ⇥ string {
if n ≻ 5 {
throw "too big"
}
return n
}
# Plain closures inside a failable function: their returns are plain values.
fn plain(int n) → int ⇥ string {
const (int) → int f ← int x → int ∴ do {
const int y ← x + 1
return y * 2
}
const (int) → int g ← int x → int ∴ x + 7
const int z ← risky(n)
return f(z) + g(z)
}
# A failable call nested in an argument, handled inside the closure.
fn handled(int n) → int ⇥ string {
const (int) → int h ← int x → int ∴ do {
var int verdict ← -1
do {
print "in §"(risky(x))
verdict ← 1
}
catch err {
verdict ← -1
}
return verdict
}
return h(n)
}
# The same closure in a function with no channel of its own.
fn handled_free(int n) → int {
const (int) → int h ← int x → int ∴ do {
var int verdict ← -1
do {
print "in §"(risky(x))
verdict ← 1
}
catch err {
verdict ← -1
}
return verdict
}
return h(n)
}
main {
do {
print plain(1)
print plain(9)
}
catch err {
print "caught: §"(err)
}
do {
print handled(2)
print handled(9)
}
catch err {
print "caught: §"(err)
}
print handled_free(3)
print handled_free(9)
}Expected output:
12
caught: too big
in 2
1
-1
in 3
1
-1