Functional record updates: with / without / merge produce new records without mutating the original
Demonstrates immutable-style field updates and that the source record is left untouched.
A Soma program from the records part of the verified corpus: 51 lines, cells RecordOps, RecordOpsTest. It passes soma check with soma 3.2.4.
How it is built
The cell RecordOps declares 5 signals in its face: base() -> Map, promoted() -> Map, anonymized() -> Map, merged() -> Map and source_unchanged() -> Bool. Handlers: base (line 14), promoted (line 19), anonymized (line 24), merged (line 29) and source_unchanged (line 33).
The file also holds 1 test cell (RecordOpsTest) with 7 assertions, run by soma test.
The source
record_ops.cell
// Functional record updates: with / without / merge produce new records
// without mutating the original. Demonstrates immutable-style field updates
// and that the source record is left untouched.
cell RecordOps {
face {
signal base() -> Map
signal promoted() -> Map
signal anonymized() -> Map
signal merged() -> Map
signal source_unchanged() -> Bool
}
on base() {
return User { name: "Ada", role: "member", age: 30 }
}
// with() returns a copy with a field replaced/added.
on promoted() {
return base() |> with("role", "admin")
}
// without() returns a copy with keys removed.
on anonymized() {
return base() |> without("name", "age")
}
// merge() overlays a second map (right wins on conflict).
on merged() {
return merge(base(), map("age", 31, "city", "London"))
}
on source_unchanged() {
let b = base()
let p = b |> with("role", "admin")
return b.role == "member" && p.role == "admin"
}
}
cell test RecordOpsTest {
rules {
assert promoted().role == "admin"
assert base().role == "member"
assert anonymized().role == "member"
assert len(without(base(), "name")) == 3
assert merged().age == 31
assert merged().city == "London"
assert source_unchanged() == true
}
}What the toolchain says
$ soma check record_ops.cell
✓ All checks passed.$ soma test record_ops.cell
test RecordOpsTest ...
✓ assert promoted().role == "admin"
✓ assert base().role == "member"
✓ assert anonymized().role == "member"
✓ assert len(without(base(), "name")) == 3
✓ assert merged().age == 31
✓ assert merged().city == "London"
✓ assert source_unchanged() == true
7 tests: 7 passed, 0 failed$ soma verify record_ops.cell
Verifying record_ops.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)