clojure-spec

pavlosmelissinos 2022-10-06T10:31:29.454499Z

I have a (s/def ::items (s/coll-of ::item :min-count 1)). How do I create a new spec from it that has some extra constraints, e.g. (s/def ::items-2 (s/coll-of ::item :min-count 1 :gen-max 6)) without repeating the common ones?

Alex Miller (Clojure team) 2022-10-06T12:05:05.731909Z

I don’t think you can easily do that

πŸ™ 1
pavlosmelissinos 2022-10-06T12:12:01.617029Z

Alright, thanks πŸ™‚ It would have been nice to have but I can work around it, so it's not a big deal.

Cora (she/her) 2022-10-06T20:27:02.497299Z

πŸ‘‹πŸ»

Cora (she/her) 2022-10-06T20:29:06.592639Z

is there a way to spec maps but without defining entities for the keys?

Alex Miller (Clojure team) 2022-10-06T20:29:35.027409Z

map? is a valid spec :)

Cora (she/her) 2022-10-06T20:29:56.936569Z

I mean a spec for a combination of specific keys with specific values

Alex Miller (Clojure team) 2022-10-06T20:30:10.725089Z

what kind of keys / what kind of values ?

Alex Miller (Clojure team) 2022-10-06T20:30:38.247709Z

you can s/and any custom predicate you might have

Cora (she/her) 2022-10-06T20:31:18.254459Z

say I want a spec for a map of {:key1 "a string" :key2 :a-keyword} without s/def :key1 and s/def :key2

Cora (she/her) 2022-10-06T20:32:24.553989Z

I can write arbitrary functions for these but it would be nice if there were a way to go just {:key1 string? :key2 keyword?}

Alex Miller (Clojure team) 2022-10-06T20:33:23.206179Z

user=> (s/def ::m (s/keys :req-un [:foo/key1 :foo/key2]))
:user/m
user=> (s/valid? ::m {:key1 "a string" :key2 :a-keyword})
true

Cora (she/her) 2022-10-06T20:33:57.532459Z

that doesn't validate the values, though?

Alex Miller (Clojure team) 2022-10-06T20:34:00.004139Z

but no, you can't get the value check without also def'ing the key specs

Cora (she/her) 2022-10-06T20:34:05.096499Z

gotcha

Cora (she/her) 2022-10-06T20:34:06.479539Z

ok

Cora (she/her) 2022-10-06T20:34:35.888599Z

for reference, with malli you can do:

[:map
   [:id string?]
   [:tags [:set keyword?]]
   [:address
    [:map
     [:street string?]
     [:city string?]
     [:zip int?]
     [:lonlat [:tuple double? double?]]]]]

souenzzo 2022-10-27T15:32:23.973629Z

btw malli is more structural https://en.wikipedia.org/wiki/Structural_type_system spec is more nominal https://en.wikipedia.org/wiki/Nominal_type_system spec will force you to give a unique name to each piece of data that you have. it is nice to have both available in clojure not a better vs worst. each one has it own advantages and penalties

Cora (she/her) 2022-10-27T16:17:46.216149Z

for sure, I just greatly prefer structural and was working on a project that only had spec

souenzzo 2022-10-27T17:28:55.637109Z

I just greatly prefer named and I'm working on a project that only had malli let's switch chairs πŸ˜‚

πŸ˜‚ 1
Cora (she/her) 2022-10-06T20:35:02.978999Z

I'm on a project using spec, though, and was hoping for something similar. sounds like I need to define the key specs

Cora (she/her) 2022-10-06T20:35:11.947949Z

thanks, Alex