(no title)
codemonkey-zeta | 4 months ago
You might make this trade off using map keys like strings or keywords, but not if you use namespace qualified keywords like ::my-namespace/id, in combination with something like spec.alpha or malli, in which case you can easily make those structural guarantees in a way that is more expressive than an ordinary type system.
bccdee|3 months ago
In the first case, it makes sense to unit test logins using every conceivable variation of `UserLoginView`s. In the second case, your surface area is much larger. `userDataMap` is full of details that are irrelevant to logins, so you only test the small relevant subset of user data variations. As the code ages and changes, it becomes harder and harder to assess at a glance whether your test data really represents all the test cases you need or not.
I worry that Clojure-style maps don't fix the problems pointed out by the article. In a codebase that passes around big dumb data objects representing important entities (incrementally processing them, updating fields, etc), the logic eventually gets tangled. Every function touches a wide assortment of fields, and your test data is full of details that are probably inconsequential but you can't tell without inspecting the functions. I don't see how Clojure solves this without its own UserLoginView-style abstraction.
codemonkey-zeta|3 months ago
- generative testing (with clojure.spec.gen.alpha/generate)
- function instrumentation (with clojure.spec.test.alpha/instrument)- automatic failure case minimization (with clojure.spec.alpha/explain + explain-data)
- data normalization / coercion (with clojure.spec.alpha/conform)
- easier refactoring - You can change specs without changing data structures
- serialization is free - maps already serialize, whereas you have to implement it with Records.
Plus you get to leverage the million other functions that already work on maps, because they are the fundamental data structure in Clojure. You just don't have to create the intermediate record, let your data be data.