clojure-spec

West 2022-05-06T04:13:54.473409Z

(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?

seancorfield 2022-05-06T04:23:10.929869Z

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

seancorfield 2022-05-06T04:23:33.008059Z

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

seancorfield 2022-05-06T04:24:10.868559Z

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

West 2022-05-06T04:25:25.737719Z

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

seancorfield 2022-05-06T04:25:30.572969Z

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

seancorfield 2022-05-06T04:25:54.125629Z

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

West 2022-05-06T04:30:28.620069Z

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

seancorfield 2022-05-06T04:31:32.202349Z

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...

West 2022-05-06T04:33:44.137699Z

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

seancorfield 2022-05-06T04:35:51.339249Z

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

West 2022-05-06T04:36:46.204769Z

Alright, maybe an adventure for another day.

seancorfield 2022-05-06T04:36:48.132469Z

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?)))

seancorfield 2022-05-06T04:37:57.584059Z

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.

seancorfield 2022-05-06T04:39:04.690829Z

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.

seancorfield 2022-05-06T04:40:00.794179Z

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

West 2022-05-06T04:41:21.488179Z

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

💯 1