I've been using spec for a while now, in a reasonably large code base (>30k 
lines of Clojure and ClojureScript) and there is an issue that bit me 
several times.

I use conformers for coercing data that is *almost* what I need, usually 
when reading from JSON (RethinkDB). Common conformers are keyword and set. 
And it works really well, except for one problem: there is no way to know 
if data has been conformed or not.

Calling s/valid? will tell me if the data is valid *if it has been 
conformed*. But what if it hasn't? Can I use the data? Is it "valid" 
according to the spec I wrote?

This is a very real problem: I've spent considerable time chasing bugs 
where there was a code path which did not call s/conform. The data passed 
all validations done with valid? and the bug manifested itself far down the 
road, where something expected a keyword instead of a string, or a set 
instead of a vector.

Here is a specific minimal example demonstrating what I'm talking about:

(ns spectest
  (:require [clojure.spec.alpha :as s]))

(s/def ::test-spec (s/and (s/conformer keyword) keyword?))

(s/conform ::test-spec "a") ;; :a
(s/valid? ::test-spec "a") ;; true

I expected the last valid? to return false, because my code does not expect 
a string, it expects a keyword, according to the spec.

I might be missing something, but I would much rather see valid? tell me if 
the data is valid for use (as supplied) and have a separate 
valid-when-conformed? which tells me if the data is, well, valid when 
conformed. It seems to me that the current valid? that does two things is 
confusing and not very useful for contracts.

At the very least I'd really like to see a function that tells me if the 
data is valid *as supplied*, as this is the function that I'd want to use 
when enforcing contracts everywhere in my code.

Alternatively, I could stop using conformers altogether, and write explicit 
data conversion functions. That might not be a bad idea, but it seems other 
people started using conformers, too, so eventually I'll hit the same 
problem again.

--J.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to