Fork me on GitHub
#clojure-spec
<
2019-12-27
>
Alexis Vincent17:12:00

why does the last example not work?

(def s-id (s/or :uuid uuid? :string string? :keyword keyword? :num number?))
(gen/generate (s/gen s-id)) ;; => works

(s/def ::id (s/or :uuid uuid? :string string? :keyword keyword? :num number?))
(gen/generate (s/gen ::id)) ;; => works

(s/def ::id s-id)
(gen/generate (s/gen ::id)) ;; => doesn't work

Alexis Vincent17:12:04

are these not equivalent?

(s/def ::id (s/or :uuid uuid? :string string? :keyword keyword? :num number?))
;; and
(def s-id (s/or :uuid uuid? :string string? :keyword keyword? :num number?))
(s/def ::id s-id)

Alexis Vincent17:12:28

Does s/def do some macro magic?

Alexis Vincent17:12:42

This is on the latest spec2 btw

seancorfield17:12:09

s/def converts the symbolic form to an actual Spec expression and then registers the spec name. So in (s/def ::id s-id) you do not have a symbolic form of a spec. It probably should give an error.

Alexis Vincent17:12:49

thanks! so would I then rather do (s/def ::id (s/spec s-id)) or something similar?

alexmiller17:12:17

Use s/register instead of s/def

Alexis Vincent17:12:31

awesome! thanks!

alexmiller17:12:52

s/register is a function and takes a spec object

👌 1
Alexis Vincent17:12:23

If I have an s/cat expression but would like to generate/validate vectors not arbitry seq’s, how would I express it?

Alexis Vincent17:12:05

(s/def :order/pair
  (s/with-gen
    (s/cat :base ::asset :counter ::asset)
    #(vec
      (gen/generate
       (s/gen
        (s/cat :base ::asset :counter ::asset))))))
This worksish. But obviously is not ideal

alexmiller17:12:07

If you’re on spec 2, you can use the new s/catv

alexmiller17:12:06

It’s difficult to do easily on spec 1

Alexis Vincent17:12:39

Perfect, thanks 🙂

seancorfield17:12:25

@alexmiller Should that (s/def ::id s-id) give an error? Or is it valid but just does something unexpected?

alexmiller18:12:51

Prob error but I’ll look at it next week

Alexis Vincent18:12:03

This is probably the same issue as before, but, are these not equiv in spec 2? The first one works nicely, but the second one blows up when generating maps from schemas that contain these keys, but not when generating them directly

(s/def :order/id (s/or :uuid uuid? :string string? :keyword keyword? :num number?))
;; vs 
(s/def ::id (s/or :uuid uuid? :string string? :keyword keyword? :num number?))
(s/def :order/id ::id)

seancorfield18:12:20

@mail024 That should probably work but there are bugs in Spec 2 that affect aliasing of specs like that, I believe.

Alexis Vincent21:12:54

If I have a schema with a qualified key I’m trying to override inline, it doesnt seem to want to use my override. It just picks the spec from the registry

(s/union
   (s/schema {:event/type #{:event.type/snapshot}})
   (s/schema
    [:event/nanotime]))
Since event/type already exists in the registry and since (I assume) it is qualified. It picks the registry definition not the one i’m declaring inline

seancorfield21:12:33

You can only use the inline specs for unqualified keys.

seancorfield21:12:11

Qualified keys are intended to be globally unique so overriding them doesn't make sense in that context (since their meaning is supposed to be globally fixed).

Alexis Vincent21:12:27

fine. Although in this case it’s the generator I want to override. Would s/with-gen work for this?

seancorfield21:12:48

Yes, possibly. Depending on exactly what you are trying to do.

Alexis Vincent21:12:43

I have a set of valid event types. Defined as a spec set. I want to define a particular message. Which is some schema, alongside a specific item from the set

seancorfield21:12:47

If you want the keys in a hash map to "depend on" the value of a particular key, it sounds like you want multi-specs

seancorfield21:12:13

If you define this as a multi-spec, it should generate correctly automatically.

Alexis Vincent21:12:56

Thanks 🙂 Ill check them out.

Alexis Vincent21:12:59

Perfect thanks. Working well