soma.cell

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.

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 next

With the fix, soma check accepts the program:

$ soma check right.cell
✓ All checks passed.