W0014: habit_warning
W0014 habit_warning — an idiom that probably does not mean what it does elsewhere.
A warning of soma check, the checker of the Soma programming language (soma explain W0014).
The rule
W0014 flags an idiom that is valid Soma but probably does not mean what it would mean elsewhere. Here ?? binds looser than arithmetic, so balances.get(owner) ?? 0 + amount reads as balances.get(owner) ?? (0 + amount): the first deposit stores amount, and every later deposit leaves the balance unchanged (a deposit of 100 then 50 gives 100, not 150). Parenthesize the default: (balances.get(owner) ?? 0) + amount.
A program that triggers it
wrong.cell
cell Wallet {
memory {
balances: Map<String, Int> [persistent]
}
on deposit(owner: String, amount: Int) {
let next = balances.get(owner) ?? 0 + amount
balances.set(owner, next)
return next
}
}What soma check prints:
$ soma check wrong.cell
warning: `balances.get(owner) ?? 0 + amount` reads as `balances.get(owner) ?? (0 + amount)` — `??` binds looser than arithmetic and comparisons; write `(balances.get(owner) ?? 0) + amount`, or parenthesize the default you meant
--> wrong.cell:6:43
|
6 | let next = balances.get(owner) ?? 0 + amount
| ^
✓ 1 warning(s), no errors.The fix field of soma check --json: Review and address the reported warning.
The fix
On line 6, let next = balances.get(owner) ?? 0 + amount becomes let next = (balances.get(owner) ?? 0) + amount.
wrong.cell → right.cell
--- wrong.cell
+++ right.cell
@@ -4,5 +4,5 @@
}
on deposit(owner: String, amount: Int) {
- let next = balances.get(owner) ?? 0 + amount
+ let next = (balances.get(owner) ?? 0) + amount
balances.set(owner, next)
return nextWith the fix, soma check accepts the program:
$ soma check right.cell
✓ All checks passed.