clojure-spec

About: http://clojure.org/about/spec Guide: http://clojure.org/guides/spec API: https://clojure.github.io/spec.alpha/clojure.spec.alpha-api.html
practicalli-john 2020-05-22T12:46:12.011100Z

I am assuming that if I am using spec keys macro, I do not also need to check the data is a hash-map. So in the following code, the map? predicate would be redundant. Can someone confirm?

(spec/def ::customer-details
  (spec/and
    map?
    (spec/keys
      :req [::first-name ::last-name ::email-address ::home-address ::social-secuirty-id])))

minimal 2020-05-22T12:47:56.011400Z

yes it’s redundant

πŸ‘ 1
alexmiller 2020-05-22T12:54:29.011800Z

s/keys does a map? check

πŸ‘ 1
2020-05-22T20:08:38.018800Z

Hello everyone. I really like Clojure.spec, it is really fun to use. I am currently wondering if there was a way to extract the default generator of a specs when using with-gen? The reason I am asking is I wish to provide more specific example than the default generator, but would still like to use the randomness of the default one. I know we can use gen/one-of, or gen/frequencies, but can we define the specific generator directly with with-gen? If not what would be a good/concise alternative to my problem, which is to define a spec with a custom generator which combine the default generator as well?

kenny 2020-05-22T20:21:03.019900Z

@neo2551 If I understand you correctly, we do this sort of thing a lot. Typically it's because of having a s/and. Here's an example of what we often have:

(s/def ::base-thing (s/keys :req [::a]))

(s/def ::thing
  (s/with-gen (s/and ::base-thing pred1? pred2?) #(gen/fmap (fn [base-thing] ) (s/gen ::base-thing))))

2020-05-22T21:33:16.024900Z

@kenny It is more if you define the ::color spec as keyword? and provide the #{:blue :red} as examples? In this case the base gen is concise, but in a more general case, I would need to copy/double the definition of my spec, will I?

2020-05-22T21:35:02.027300Z

I would still like to retain the ability to generate random keywords, while using my blue and red examples. One solution is gen/one-of, but I don’t see how I can get the random one without copying the base spec again.

kenny 2020-05-22T21:39:10.027600Z

(def colors #{:blue :red})
(s/def ::color (s/with-gen keyword? #(gen/one-of [(s/gen colors) (s/gen keyword?)])))
?

2020-05-22T21:41:38.028400Z

What if keyword? was some really long spec?

kenny 2020-05-22T21:42:25.028700Z

(s/def ::color (s/or :predefined #{:blue :red}
                     :other keyword?))

kenny 2020-05-22T21:42:51.029Z

I'm not really sure I understand your problem πŸ™‚