I know what conform does, and I can imagine maybe sometimes needing it, but in practice I’ve never found use for it. I’m curious to hear about other people’s use cases for conform and how it came in handy.
(ugh, discourse doesn’t allow me to add a post with less than 20 characters in it, so here’s some useless noise to please our robot overlords)
Pretty useful for parsing a flexible function signature. I get both a nicely structured map and guarantees that it is in valid shape.
I use it for parsing incoming data in a semi-structured format. For example, I wrote some code to auto-generate a spec from an Apache AVRO specification (a kind of typed data structure specification) and then
s/conform a bunch of semi-structured json using conformers that are quite liberal in their accepted inputs (for example, a
boolean-conformer I wrote accepts
"y" and produces
true; conversely it accepts
"n" and produces
It’s really really convenient to write simple parsing code so that your specs can be useful threefold: parse semi-structured data, validate it, and generate random data.
However note the following discussion: https://stackoverflow.com/questions/45188850/is-use-of-clojure-spec-for-coercion-idiomatic
Alex Miller, of the Cognitect clojure.core team, reiterates the official position on the Clojure mailing list 20 February 2018:
We recommend that you not use conformers for coercion
We use s/conform as a pass-through step which hands on an input if valid or hands on :s/invalid.
I wondered whether we should be coercing at the same step as I’ve often promoted Postels law i.e. to be liberal about inputs and really only very tightly validate outputs to allow flexibility to handle rubbish inputs stuck in cruddy old data etc.
However I think I can agree with the “official” position (no such thing of course!) that this is a separate responsibility. The spec should specify only the actual business constraints of given bit of data associated with a (hopefully fully namespaced) key, and not the coercion steps needed to parse, canonicalize, clean up, coerce, deserialise, munge etc data from whatever source it comes…