You’re right about OCam’ (and Elmls) behaviour and I wasn’t trying to suggest otherwise.
I think you also understood my post perfectly well.
Constructing a new record from scratch will give a type error when a new field is added, but a with-expression won’t.
That’s a good question. Why should one expect a with-expression to give type errors when a new field is added, when adding the field to a nested record instead can encourage upholding invariants (like all relevant fields being changed together), and also give better semantic grouping?
I thought about your question for a bit. I tend to prefer flatter records because nested records can come with their own sort of pain (not unlike manually deconstructing and reconstructing records actually…), which is probably why I didn’t consider it.
I think the solution of using nested records kind of kicks the can further down the road though, because a nested record itself may have many fields and multiple invariants to track, and continually nesting will add lots of layers of indirection, which is a pain for field access and for updating.
I’ll probably have a go at banning with-expressions in my code except for an “update-type” module (similar to, uh, OOP setters for a class I guess
) and see how that works.
If all record updates go through a function call instead of using with directly, it should be easier to uphold invariants hopefully.
Adding a field to a record would then cause one to inspect the update-type module, add additional parameters to functions as necessary, and then the rest of the refactoring process should (hopefully) be quite mechanical. That sounds easier and less error-prone than allowing with expressions anywhere, and scanning every part of the codebase to check that they all do what they are meant to with the new field.
I’m sorry for how long-winded this post is.
I thought it was worth documenting my thought process in case anyone else sees value in it.
Thanks for your reply and encouraging me to think about the problem some more @Chet_Murthy. I appreciate it.