soma.cell

left_join keeps every left row even when the right side has no match

Products joined to a sparse stock table; unmatched products keep their fields but gain no stock columns. Demonstrates the ?? guard for missing data.

A Soma program from the data part of the verified corpus: 54 lines, cells Inventory, InventoryTests. It passes soma check with soma 3.2.4.

How it is built

The cell Inventory has no face and no memory. Handlers: products (line 6), stock (line 15), joined (line 24), availability (line 27), out_of_stock (line 34) and run (line 36).

The file also holds 1 test cell (InventoryTests) with 4 assertions, run by soma test.

Generated from soma describe on this file.

The source

left_join_inventory.cell

// left_join keeps every left row even when the right side has no match.
// Products joined to a sparse stock table; unmatched products keep their
// fields but gain no stock columns. Demonstrates the ?? guard for missing data.

cell Inventory {
    on products() {
        return list(
            map("sku", "P1", "name", "Bolt",   "price", 5),
            map("sku", "P2", "name", "Nut",    "price", 3),
            map("sku", "P3", "name", "Washer", "price", 1),
            map("sku", "P4", "name", "Gasket", "price", 8)
        )
    }

    on stock() {
        return list(
            map("sku", "P1", "on_hand", 200),
            map("sku", "P3", "on_hand", 0),
            map("sku", "P4", "on_hand", 45)
        )
    }

    // Every product survives; P2 has no stock row.
    on joined() { return products() |> left_join(stock(), "sku") }

    // Default missing on_hand to 0 with ??.
    on availability() {
        return joined() |> map(r => {
            let qty = r.on_hand ?? 0
            r |> with("available", qty > 0)
        })
    }

    on out_of_stock() { return availability() |> filter_by("available", "=", false) |> pluck("name") }

    on run() {
        for r in availability() { print("{r.name}: {r.on_hand ?? 0} on hand") }
        return out_of_stock()
    }
}

cell test InventoryTests {
    rules {
        // left join keeps all 4 products
        assert len(joined()) == 4
        // P2 (no match) and P3 (zero stock) are out of stock
        assert len(out_of_stock()) == 2
        // P1 has 200 on hand
        assert (availability() |> filter_by("sku", "=", "P1"))[0].on_hand == 200
        // P2 missing on_hand defaults to unavailable
        assert (availability() |> filter_by("sku", "=", "P2"))[0].available == false
    }
}

What the toolchain says

Run on a fresh copy of the program at build time; the outputs are pasted unedited.

$ soma check left_join_inventory.cell
✓ All checks passed.
$ soma test left_join_inventory.cell
test InventoryTests ...
  ✓ assert len(joined()) == 4
  ✓ assert len(out_of_stock()) == 2
  ✓ assert (availability() |> filter_by("sku", "=", "P1"))[0].on_hand == 200
  ✓ assert (availability() |> filter_by("sku", "=", "P2"))[0].available == false

4 tests: 4 passed, 0 failed
$ soma verify left_join_inventory.cell
Verifying left_join_inventory.cell...
No state machine in this program: nothing to prove beyond `soma check` (invariants and lifecycles are what verify proves).
VERIFY OK (vacuous — no state machine)

Builtins used

filter_by, left_join, len, list, map, pluck, print, with

Source file: /corpus/data/left_join_inventory.cell · examples/corpus/data/left_join_inventory.cell