Fork me on GitHub
#clojure-spec
<
2018-01-15
>
gfredericks02:01:24

user> (s/valid? (sorted-set 1 2 3) "you'd think this would return false")
;; throws
ClassCastException java.base/java.lang.Long cannot be cast to clojure.lang.Keyword  clojure.lang.Keyword.compareTo (Keyword.java:114)

andy.fingerhut02:01:13

stack trace shows it is trying to call (s/regex? (sorted-set 1 2 3)), which raises that same exception.

andy.fingerhut03:01:17

workaround: (s/valid? (hash-set (sorted-set 1 2 3)) ...)

gfredericks03:01:49

this makes me think the answer will be "you can't use sorted sets as specs"

andy.fingerhut03:01:11

I looked for a CLJ issue that I thought existed about making set lookup on sorted sets never return an exception because of exceptions thrown by the comparison function, but not sure if I am imagining it.

gfredericks03:01:19

even if it didn't fail at that point, a sorted set is not a general predicate 😕

gfredericks03:01:05

making a change like that would be weird because what if you supply a buggy comparison function to sorted-set-by, for instance? it would just swallow them

gfredericks03:01:28

it could throw them on insert I guess, but would swallow on lookup

andy.fingerhut03:01:13

Found several related tickets on sorted sets, but not the one I was imagining. My imagination can be vivid.

bronsa09:01:48

@andy.fingerhut yeah I know which ticket you’re talking about

bronsa09:01:50

it was https://dev.clojure.org/jira/browse/CLJ-1242 which got refocused just on equality, but originally was about equality and lookup

conan14:01:03

Is there a way to get the keys back from a map spec? i.e. the function get-keys:

(s/def ::banana (s/keys :req [::length ::type] 
                        :opt [::colour]))

(get-keys ::banana)
=> {:req [::length ::type]
    :opt [::colour]}
I can do this by using (s/form ::banana) but that just gives me a sequence so seems very brittle

andre.stylianos15:01:34

I don't think there's a better way for now, there's an issue in Jira that seems likely to be what you want but it's still open. https://dev.clojure.org/jira/browse/CLJ-2112

ikitommi15:01:09

@U053032QC forms have been stable, so (->> (s/form ::banana) rest (apply hash-map)) while waiting the specs for specs.

conan15:01:01

@U485ZRA58 yes that does look like what I want. @U055NJ5CC yep, it certainly gets me exactly what i want, it just seems a bit wonky

Alex Miller (Clojure team)17:01:30

there is likely to be more support for this in the next major update for spec

souenzzo17:01:42

(let [spec (s/keys :req [:foo/bar])
      _ (s/def ::req (s/coll-of keyword?))
      keys-spec (s/cat :op symbol?
                       :args (s/keys* :opt-un [::req]))
      {{:keys [req]} :args} (s/conform keys-spec (s/form spec))]
  req)
@alexmiller, you always say to "not use conform to coerce values". In this case, we are using conform to "parse" a struct. It's a valid use? read the topic

Alex Miller (Clojure team)17:01:50

I don’t think I’ve said that. conform is designed to conform values so I’m not even sure what you mean.

Alex Miller (Clojure team)17:01:11

this seems like a pretty ugly workaround (the embedded s/def seems like an obvious place where you could have issues too)

souenzzo17:01:36

(it's just to fit on let to easy copy'n'paste on repl) I think that you say do not use conform to conform values related to CLJ-2116

Alex Miller (Clojure team)17:01:32

do you mean “do not use conformers to coerce values” which is a very different statement?

Alex Miller (Clojure team)17:01:55

that seems wholly unrelated to your example if so

souenzzo17:01:09

YEP. Sorry. I got lost with the words 😞

souenzzo17:01:42

(let [spec (s/keys :req [:foo/bar])
      _ (s/def ::req (s/coll-of keyword?))
      keys-spec (s/cat :op symbol?
                       :args (s/keys* :opt-un [::req]))
      {{:keys [req]} :args} (s/conform keys-spec (s/form spec))]
  req)
@alexmiller, you always say to "not use conform to coerce values". In this case, we are using conform to "parse" a struct. It's a valid use? read the topic

Alex Miller (Clojure team)17:01:02

I don’t think what you’re doing here is related to coercion

Alex Miller (Clojure team)17:01:12

which is independent from whether it’s good :)

Alex Miller (Clojure team)17:01:53

my real question is why you want to ask this question in the first place and whether you can arrange things to not ask it

Steve Peterson23:01:09

Hi Spec-cers! Which Clojure libraries are using Spec as a protection layer in their APIs, i.e. to validate args? Are they instrumenting API fns “by default” so input args are checked on each call?