soma.cell

E0091: foreign_idiom

E0091 foreign_idiom — syntax carried over from another language.

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

The rule

Names that other languages use for null, booleans, bindings or functions (null, None, nil, True, var, def, this, and, or, not, …) do not exist in Soma, and soma check reports them as E0091 instead of a plain undefined name. The message names the Soma form: null is (), booleans are true / false, bindings are let, and the boolean operators are &&, ||, !. Here n == null becomes n == (); stock.get(sku) ?? 0 would also do.

A program that triggers it

wrong.cell

cell Inventory {
    face {
        signal stock_of(sku: String) -> Int
        signal restock(sku: String, qty: Int) -> Int
    }
    memory {
        stock: Map<String, Int> [persistent]
    }
    on stock_of(sku: String) {
        let n = stock.get(sku)
        if n == null { return 0 }
        return n
    }
    on restock(sku: String, qty: Int) {
        let n = (stock.get(sku) ?? 0) + qty
        stock.set(sku, n)
        return n
    }
}

What soma check prints:

$ soma check wrong.cell
error: 'null' does not exist in Soma — Soma's null is `()`: `if x == () { … }`, `x ?? default`
  --> wrong.cell:11:17
   |
11 |         if n == null { return 0 }
   |                 ^
  = code: E0091
✗ 1 error(s), 0 warning(s).

The fix field of soma check --json: Soma's null is `()`: `if x == () { … }`, `x ?? default`

On line 11, if n == null { return 0 } becomes if n == () { return 0 }.

wrong.cell → right.cell

--- wrong.cell
+++ right.cell
@@ -9,5 +9,5 @@
     on stock_of(sku: String) {
         let n = stock.get(sku)
-        if n == null { return 0 }
+        if n == () { return 0 }
         return n
     }

With the fix, soma check accepts the program:

$ soma check right.cell
✓ All checks passed.