Idiomdrottning’s homepage

Separating schema from selection

In this 2018 talk at Clojure Conj, Rich Hickey proposes separating “schema” from “selection”.

The example he gives (in pseudocode) is this:

(s/def ::street string?)
(s/def ::city string?)
(s/def ::state state-code?)
(s/def ::zip int?)
(s/def ::addr (s/schema [[::street ::city ::state ::zip]]))

(s/def ::id int?)
(s/def ::first string?)
(s/def ::last string?)
(s/def ::user (s/schema [[::id ::first ::last ::addr]]))

for the schema, and then using those schemata in selections like

(get-movie-times
 user =>
 (s/select ::user [::id ::addr {::addr [::zip]}]))

or

(place-order
 user =>
 (s/select ::user
           [::first ::last ::addr
                    {::addr [::street ::city ::state ::zip]}]))

(Or, he wrote :: city with an extra space in there but we get the gist.)

And I’m, at first, like: “That’s great!”

(He had already won me over by slagging Haskell’s “Maybe” type, something I have also been ragging on. The more I get into Clojure the more I find that they’ve been a couple of steps ahead of me on the same sorta stuff I’ve been writing about for the past year or so♥.)

But then I’m like wait a minute… If you’ve got the “selection”, why the heck do you even need the schema?

Don’t we wanna single-point-of-truth this stuff? And the “selection” is clearly holding “the truth”. A user in the context of someone requesting movie times is a user id and a zip code. That’s the “truth” in the context of that selection. The schema isn’t doing much—on the leaf level, sure, it’s specifying that it’s ints we’re requesting, but there’s nada on the tree level. The schema is just sitting there like a moldy peach.

If we can define and reference vars, we can handle both the leaf issue (the int checking) and we can also reuse parts of schema.

That’s what Rich wanted in the first place; to reuse schemata between requirement and production.

Additionally, and I know that this was just placeholder syntax, but it’s super cumbersome to

{::addr [::street ::city ::state ::zip]}

Even in Zork we could get everything from the mailbox.

The human compiler at work.💔