soma.cell

E0107: ambiguous_slot

E0107 ambiguous_slot — a slot name two cells declare.

A compile-time error of soma check, the checker of the Soma programming language (soma explain E0107).

The rule

A test cell may read a memory slot by its bare name, but when two cells declare a slot of that name (Orders.totals and Refunds.totals), the name does not say which one is meant, and soma check reports E0107 at the read. Read the value through a handler of the cell you mean, here a total_of(id) signal on Orders.

A program that triggers it

wrong.cell

cell Orders {
    face { signal place(id: String, cents: Int) -> Int }
    memory { totals: Map<String, Int> [persistent] }
    on place(id: String, cents: Int) {
        totals.set(id, cents)
        return totals.size
    }
}

cell Refunds {
    face { signal refund(id: String, cents: Int) -> Int }
    memory { totals: Map<String, Int> [persistent] }
    on refund(id: String, cents: Int) {
        totals.set(id, cents)
        return totals.size
    }
}

cell test OrderTests {
    rules {
        let n = place("o1", 2500)
        assert totals.get("o1") == 2500
    }
}

What soma check prints:

$ soma check wrong.cell
error: `totals` is a slot of several cells (Orders, Refunds) — in a test it is ambiguous: read it through a handler of the cell you mean
  --> wrong.cell:22:16
   |
22 |         assert totals.get("o1") == 2500
   |                ^
  = code: E0107
✗ 1 error(s), 0 warning(s).

The fix field of soma check --json: in a test it is ambiguous: read it through a handler of the cell you mean

Line 2 is rewritten; 1 line is added after line 7; on line 22, assert totals.get("o1") == 2500 becomes assert total_of("o1") == 2500.

wrong.cell → right.cell

--- wrong.cell
+++ right.cell
@@ -1,4 +1,7 @@
 cell Orders {
-    face { signal place(id: String, cents: Int) -> Int }
+    face {
+        signal place(id: String, cents: Int) -> Int
+        signal total_of(id: String) -> Int
+    }
     memory { totals: Map<String, Int> [persistent] }
     on place(id: String, cents: Int) {
@@ -6,4 +9,5 @@
         return totals.size
     }
+    on total_of(id: String) { return totals.get(id) ?? 0 }
 }
 
@@ -20,5 +24,5 @@
     rules {
         let n = place("o1", 2500)
-        assert totals.get("o1") == 2500
+        assert total_of("o1") == 2500
     }
 }

With the fix, soma check accepts the program:

$ soma check right.cell
✓ All checks passed.