soma.cell

W0012: native_semantics

W0012 native_semantics — native code that would differ from the interpreter.

A warning of soma check, the checker of the Soma programming language (soma explain W0012).

The rule

/ in Soma is exact division, so on two Ints it can give a Float (7 / 2 is 3.5), in [native] handlers as in the interpreter; soma check warns with W0012 when a [native] handler divides two Ints, because where the result must be an Int a non-exact quotient fails at run time. Here unit_price(10, 4) stops with "the face declares -> Int but the handler returned Float 2.5". Write idiv(a, b) for the integer quotient (truncated toward zero); soma fix --native-idiv makes that rewrite.

A program that triggers it

wrong.cell

cell Pricing {
    face {
        signal unit_price(total_cents: Int, quantity: Int) -> Int
    }
    on unit_price(total_cents: Int, quantity: Int) [native] {
        if quantity <= 0 { return 0 }
        return total_cents / quantity
    }
}

What soma check prints:

$ soma check wrong.cell
warning: in Pricing.unit_price [native]: `/` on two Ints is a Float (7 / 2 = 3.5); where the result must be an Int a non-exact quotient is a runtime error — 1 occurrence. Write idiv(a, b) for an integer quotient (`soma fix --native-idiv` rewrites them)
  --> wrong.cell:5:5
  |
5 |     on unit_price(total_cents: Int, quantity: Int) [native] {
  |     ^
✓ 1 warning(s), no errors.

The fix field of soma check --json: Review and address the reported warning.

On line 7, return total_cents / quantity becomes return idiv(total_cents, quantity).

wrong.cell → right.cell

--- wrong.cell
+++ right.cell
@@ -5,5 +5,5 @@
     on unit_price(total_cents: Int, quantity: Int) [native] {
         if quantity <= 0 { return 0 }
-        return total_cents / quantity
+        return idiv(total_cents, quantity)
     }
 }

With the fix, soma check accepts the program:

$ soma check right.cell
✓ All checks passed.