clojure-spec 2022-05-06

(s/def ::params (s/or :string string?
                      :map map?))

(defn is-null? [val]
  (or (empty? val)
      (= "null" val)
      (nil? val)))

(s/def ::non-null-params
  (s/and ::params
         #(not (is-null? %))))

(gen/sample (s/gen ::non-null-params))
Why does ::non-null-params still give me empty maps and empty strings?

Because s/or produces a pair. Either [:string s] or [:map m]

is-null? could have [[_ val]] as its arglist and it will work.

Or you could test (is-null? (second %))

Ah ok. Then clearly I didn't want to use s/or I wanted to choose one or the other.

(technically it's a MapEntry so (val %) is "more correct" than (second %)

s/or is how you do it, but it returns a tagged pair to tell you which branch matched.

(s/def ::non-null-params
  (s/and ::params
         #(not (is-null? (val %)))))
Thanks Sean. It's working just as expected!

I think Alex has said that Spec 2 will have a non-conforming or that doesn't do that, or at least some easy way to avoid it...

"Will have", as in "when it's released", or "is being talked about". Can I test it now?

It's only available via git deps and it's kind of buggy.

Alright, maybe an adventure for another day.

What you can do with Spec 1 is used the undocumented nonconforming function, which is currently documented for Spec 2 (but might go away -- it will still be in Spec 1 tho'):

(s/def ::params (s/nonconforming (s/or :string string? :map map?)))

Spec 1 isn't going away. Spec 2 will most likely morph into the actual "core" Spec at some point and folks will either migrate from Spec 1 to "Spec" or use both side-by-side.

For a while at work, we maintained a branch of our code base migrated to use Spec 2, and help Alex test stuff, but it was such a moving target and several places were buggy and/or incomplete so after several months we abandoned trying to keep our branch updated and decided to wait for Spec 2 to mature.

Spec 2 has a lot of improvements over Spec 1 but it is also quite different in several places.

Either way, I'm excited to see how it turns out.

💯 1