Fork me on GitHub
#clojure-spec
<
2016-09-23
>
devn00:09:38

@noprompt: what mad science are you up to now? :)

noprompt00:09:18

@devn my problem is that i want to conform nested string data so i don't need to do it in two steps. it's possible to use conformer but when there's a problem the error message is really, really bad (and there's nothing available in the public api for custom explanations). i'd like to simply write a custom spec against the protocols but alexmiller, in a previous discussion, has cautioned against that.

noprompt00:09:48

basically i'm at a crossroads where it's either write the data portion of the parser by hand, forgoing spec, or bend spec to do my bidding.

kenny00:09:02

How do you spec a function with optional args that should be conformed to a map?

(defn foo
  [& {::keys [bar]}]
  ;...
  )

kidpollo00:09:16

hmmm sounds interesting and actually useful @noprompt It might actually also help my use case

kidpollo01:09:17

when an input param for example is a string but the string contains an elastic search query

kidpollo01:09:49

an extra ste would need to be made to validate the syntax of the string

kenny01:09:03

This is a more concrete example:

(s/conform (s/and #(even? (count %))
                  (s/conformer (partial apply hash-map))
                  (s/keys :req [::foo]))
           [::foo true])
There must be a better way of handling this for optional map args in fns

bfabry01:09:22

@kenny keys* is for this

kenny01:09:42

Ah! Perfect!

bfabry01:09:49

I knew I'd seen a specific function for it but it took me ages to find that again

Alex Miller (Clojure team)01:09:33

@noprompt I will stick with my caution in trying to use spec regex to parse strings - that's not what it's designed for and I a normal regex is going to be a better choice. Why cant you use a regex predicate?

djpowell14:09:46

what is the recommended way to make a spec for a constant string?

donaldball14:09:31

I put it in a set

djpowell14:09:08

ooh - gen/return maybe?

djpowell14:09:07

ah yeah, a set seems to work ok

Alex Miller (Clojure team)15:09:16

yes, a set #{“foo”}

misha17:09:13

good day! is there a way to spec a function, which I expect to get as an argument? like "I expect function of 2 arguments: int and string"

misha17:09:09

so far I see only s/fdef, which expects a symbol identical to existing function name.

bfabry17:09:57

^ yes 🙂

bfabry17:09:41

also, something which I think is a bit not clear from the docs, fdef adds an fspec to the registry under the fully qualified name of the function, so if you've written an fdef for foo, you can use the symbol `foo in place of a spec

spieden18:09:00

anyone know how to spec a map by predicates over its keys and values? really expected this to work:

(s/explain (s/+ (s/cat :foo string? :bar keyword?)) {"hi" :bye})
In: [0] val: ["hi" :bye] fails at: [:foo] predicate: string?

spieden18:09:34

@bfabry thanks! ok, now just for academic interest:

(s/explain (s/+ (s/cat :foo string? :bar keyword?)) [["hi" :bye]])

spieden18:09:08

ah looks like i want “every"

bfabry18:09:12

a map is also I believe a sequence of tuples, not a single long sequence of key,val,key,val

spieden18:09:10

yeah i guess i was expecting the regular expression to match multiple instances of [“hi” :bye] within the sequence

bfabry18:09:17

so this works

boot.user=> (s/explain (s/+ (s/spec (s/cat :foo string? :bar keyword?))) {"hi" :bye})
Success!
nil

bfabry18:09:01

as does this

boot.user=> (s/explain (s/+ (s/tuple string? keyword?)) {"hi" :bye})
Success!
nil

bfabry18:09:36

but like I said, the simplest way to spec it is

boot.user=> (s/explain (s/map-of string? keyword?) {"hi" :bye})
Success!
nil

spieden18:09:26

that’s what i’m going with. thanks

noprompt21:09:12

@alexmiller i can't use regex in my case because the strings i'm parsing are context-free.

Alex Miller (Clojure team)21:09:08

so use a parser like instaparse?

noprompt21:09:36

@alexmiller i probably would but unfortunately the story for clojurescript isn't solidified yet on that account.

Alex Miller (Clojure team)21:09:04

@bfabry I would not use s/+ for that example above but (s/every (s/tuple string? keyword?)) - that’s basically (minus things like :kind and :into) what map-of translates to

noprompt21:09:09

even still, the story for plugging into explainability with conformer is just not good enough. yes, the result does tell what string is wrong but i'm not able to say where in the string something is wrong.

noprompt21:09:51

to be sure, i'm not complaining about spec. it's already saved me a huge amount of work. if i could tap into explainability it'd be a closed case for me.

Alex Miller (Clojure team)21:09:41

not sure what to tell ya - you’re asking for things spec is unlikely to provide ¯\(ツ)

noprompt21:09:02

why wouldn't spec want to expose hooks to explainability?

Alex Miller (Clojure team)21:09:29

because one of the ideas in spec is to make explainability generic

noprompt21:09:51

that presupposes that such an idea is possible.

Alex Miller (Clojure team)21:09:55

I haven’t talked with Rich about this specifically so this is just my read on it

noprompt21:09:10

(not saying it's not)

Alex Miller (Clojure team)21:09:17

when you get to a predicate the explanation is: the predicate failed

Alex Miller (Clojure team)21:09:47

if you want more detail, make finer-grained predicates and combine them

Alex Miller (Clojure team)21:09:26

if you want that + some sort of string parsing, I think you’re into the territory of custom specs

noprompt21:09:30

right, however, sometimes the context is a little more granular e.g. failure alone is not enough for reporting. sometimes there's additional context for why the predicate failed.

noprompt21:09:57

can we get a promise to stabilize the protocols? 🙂

noprompt21:09:15

i meant when 1.9 is stable.

noprompt21:09:38

honestly, that would be phenomenal for my use case.

Alex Miller (Clojure team)21:09:44

I don’t have an answer on that

Alex Miller (Clojure team)21:09:45

we can provide guidance when things move past alpha

noprompt21:09:49

chances are most folks won't be interested in implementing the protocols and will just use "stock" spec. a handful of people, like myself, would probably greatly appreciate and benefit from the protocols being stable.

noprompt21:09:15

would this conversation be better on the dev mailing list?

Alex Miller (Clojure team)21:09:42

doesn’t make any difference to me

noprompt21:09:55

fair enough.