E0081: lambda_scope
E0081 lambda_scope — a lambda reads a name that is not in scope where it runs.
A compile-time error of soma check, the checker of the Soma programming language (soma explain E0081).
The rule
A lambda captures only the locals bound before it, so a lambda that calls itself (or a lambda bound later in the block) cannot see that name; check refuses it rather than letting it fail at run time. For recursion write a handler, on walk(k: Int) { ... }, which can call itself.
A program that triggers it
wrong.cell
cell Countdown {
on total_steps(n: Int) {
let walk = k => if k <= 0 { 0 } else { k + walk(k - 1) }
return walk(n)
}
}What soma check prints:
$ soma check wrong.cell
error: the lambda `walk` calls `walk`, which it cannot see: a lambda captures the locals bound before it — for recursion write a handler (`on walk(…)`)
--> wrong.cell:3:20
|
3 | let walk = k => if k <= 0 { 0 } else { k + walk(k - 1) }
| ^
= code: E0081
✗ 1 error(s), 0 warning(s).The fix field of soma check --json: for recursion write a handler (`on walk(…)`)
The fix
4 lines are added after line 1; line 3 is removed.
wrong.cell → right.cell
--- wrong.cell
+++ right.cell
@@ -1,5 +1,8 @@
cell Countdown {
+ on walk(k: Int) {
+ if k <= 0 { return 0 }
+ return k + walk(k - 1)
+ }
on total_steps(n: Int) {
- let walk = k => if k <= 0 { 0 } else { k + walk(k - 1) }
return walk(n)
}With the fix, soma check accepts the program:
$ soma check right.cell
✓ All checks passed.