Fork me on GitHub
#clojure-spec
<
2017-04-11
>
madstap00:04:58

Woops, that is actually just

(defmacro specondp
  {:style/indent 1}
  [expr & clauses]
  `(condp s/valid? ~expr ~@clauses))
Probably doesn't need to be a macro...

Oliver George02:04:24

I do look forward to instrumentation on clojure.core

Oliver George02:04:03

Perhaps I'm wishing but imagine it would have saved me this headache. (cljs.reader/read-string (str (keyword "3asdf")))

Oliver George02:04:28

That throws a mysterious error since we're trying to read a keyword which starts with a number.

Oliver George02:04:16

(my use case was using js->clj keywordize-keys to turn json into clojure data structures and later serialising to js/localStorage)

Oliver George02:04:43

A spec on the keyword function would have picked up the illegal input (I believe)

hiredman03:04:56

The core team has repeatedly stated that those keywords are not illegal, the keyword function is just able to create a wider range of keywords than the reader

Oliver George04:04:08

Is that right. Huh. It was a bugger to find my unexpected keyword. I guess I'd be happy for the error thrown in read-string to improve.

stathissideris04:04:58

@madstap yes, that would be the basic version, but I was thinking about something that actually binds local vars in the same way that core.match does

stathissideris04:04:04

With var names derived from the keyword names in s/cat

cfleming04:04:48

@olivergeorge It’s worse than that - using the function you can create keywords with spaces in them, or anything else your heart desires.

cfleming04:04:06

Feel like a keyword with a newline in it? No problem.

Oliver George04:04:02

Yeah that's a nasty surprise. Seems like a spec instrument on clojure.core/keywords would help to protect me nicely.

Oliver George04:04:25

As it is I'll log a ticket for improving read-keyword so that it's blindly obvious when the specific issue I came up with occurs.

Oliver George04:04:28

@alexmiller I gather adding spec's to the core ns's is complicated by aot compilation (or similar). Does that mean user defined optional core ns specs will be difficult/troublesome?

Oliver George04:04:56

@cfleming have you found any good opportunities for Cursive to integrate/leverage specs?

Oliver George04:04:33

(I wondered if it could be used to improve autocomplete suggestions)

cfleming04:04:10

There are plenty, but I haven’t had time to investigate it yet. It could definitely be used to improve autocomplete, yes, assuming the spec machinery provides enough hooks to get that info out.

ikitommi07:04:59

Hmm.. s/merge seems to report problems of qualified keys twice:

(require ’[clojure.spec :as s])

(s/def ::a int?)
(s/def ::b string?)

(s/explain-data
  (s/merge
    (s/keys :req-un [::a])
    (s/keys :req-un [::b]))
  {:a 1 :b 2})
; #:clojure.spec{:problems ({:path [:b], :pred string?, :val 1, :via [:user/b], :in [:b]})}

(s/explain-data
  (s/merge
    (s/keys :req [::a])
    (s/keys :req [::b]))
  {::a 1 ::b 1})
;#:clojure.spec{:problems ({:path [:user/b], :pred string?, :val 1, :via [:user/b], :in [:user/b]}
;                          {:path [:user/b], :pred string?, :val 1, :via [:user/b], :in [:user/b]})}

akiel08:04:49

As I read the doc on s/& this (s/conform (s/& (s/+ char?) #(apply str %)) [\s \p \e \c]) should return "spec" but returns [\s \p \e \c]. Am I wrong?

akiel08:04:44

(s/conform (s/& (s/+ char?) (s/conformer #(apply str %))) [\s \p \e \c]) returns "spec". I debugged the code and s/& calls dt with cpred? nil. So maybe it should use cpred? true here?

akiel09:04:23

Juste require shepherd.spec without any alias and use :principle/type

wottis09:04:45

@akiel thank you very much!

Alex Miller (Clojure team)12:04:31

@akiel s/& just validates the predicate then returns the conformed value of the spec so that is the expected behavior. You could switch it to s/and though and use s/conformer for the last bit

Alex Miller (Clojure team)12:04:04

@ikitommi it's reporting the same bug from each branch of the merge. Not sure if those should be deduped or not

ikitommi12:04:34

I think it should, as it works with unqualified keys.

Alex Miller (Clojure team)12:04:25

@olivergeorge you can add user-defined specs to core. Works fine. We have no plans to place a spec on keyword any narrower than string? though. What would be a useful enhancement though is to have either a predicate or "safe" version of keyword that accepted only print-read-safe keywords

Alex Miller (Clojure team)12:04:38

keyword-strict or something

Alex Miller (Clojure team)12:04:11

And then you could use that in json parsing etc

akiel12:04:38

@alexmiller The doc of s/& says: takes a regex op re, and predicates. Returns a regex-op that consumes input as per re but subjects the resulting value to the conjunction of the predicates, and any conforming they might perform. especially: but subjects the resulting value and any conforming they might perform I read that as if the cvals of the preds should be returned. The same as s/and is doing, as you say.

Alex Miller (Clojure team)13:04:42

Hmm, not sure. I would need to ask Rich.

ikitommi15:04:00

@alexmiller wrote an jira issue of that double problems, also another of s/keys* is returning something that is not a clojure.spec.Spec

bronsa15:04:49

@ikitommi no regex op return specs tho

bronsa15:04:19

same for s/cat, s/+ etc

ikitommi17:04:54

well, now that I look at the clojure.spec test suite, no wonder there are (form) bugs. @alexmiller, is there a way to contribute more tests? testing all forms & return values as Specs would easily reveal all things that don’t work right now.

ikitommi18:04:08

one more form bug:

(require '[clojure.spec :as s])

(s/def ::a int?)
(s/form (s/& ::a))
; (clojure.spec/& #object[clojure.spec$spec_impl$reify__13797 0x47b888f9 "clojure.spec$spec_impl$reify__13797@47b888f9"])

bronsa18:04:23

@ikitommi i think that's by design (regex ops not being specs)

Alex Miller (Clojure team)19:04:43

correct, that’s as intended (those respond to regex?

Alex Miller (Clojure team)19:04:38

regarding & forms, that problem space is related to the issues with the keys* form (which is implemented with &). would be fine to log though.

Oliver George21:04:44

Thanks @alexmiller I'm happy with those options.

Alex Miller (Clojure team)21:04:20

@olivergeorge I’ve talked about these before with people but I don’t think it was ever actually logged

Oliver George22:04:08

I wonder where that documentation should live.

Oliver George22:04:38

Adding a keyfn option to js->clj would make it easier to step safely around the sharp edges

Oliver George22:04:22

There is an open ticket to improve cljs.reader/read-keyword to produce a better error here: http://dev.clojure.org/jira/browse/CLJS-1907

waffletower23:04:30

If this is a reasonable place to ask about generators… I am trying to understand clojure.test.check.generators/no-shrink. I have tried to eliminate shrinking in this generator example:

(def large-flat-natural
  (gen/no-shrink (gen/fmap abs gen/large-integer)))

waffletower23:04:50

But it gives shrunken results:

(repeatedly 16 #(println (gen/sample large-flat-natural 24)))

(1 0 1 2 1 15 1 0 5 5 7 76 2 109 3 234 99 41987 18 9 17237 45920 1019 14841)
(0 1 1 0 2 1 5 5 46 3 177 0 6 169 23 25 25 5 367 1420 311458 36483 42628 1)
(0 0 0 0 4 2 1 0 71 1 5 35 22 208 26 11 3 8391 32493 232365 2 2 2750 5576)
(1 1 1 0 0 1 2 2 3 6 6 19 1 55 3 2 33 20263 1877 1 362177 2 6258 15641)
(1 0 1 2 2 2 6 58 0 26 66 39 1860 1 347 4 9073 6 19852 31997 25 56137 117428 23)
(0 1 1 2 0 1 1 0 31 13 1 116 3 105 1 26 8959 710 38835 4 1701 0 91091 27453)
(0 1 0 2 1 8 7 15 2 8 4 9 35 1254 0 22 20463 1 170 2 15412 1 0 23163)
(1 1 0 1 1 1 14 1 2 1 31 141 1 3 409 15 19 7946 49819 55 3831 44642 1 510806)
(0 1 1 1 1 1 8 1 1 21 3 2 32 0 504 1 4 0 1 2737 24695 2701 242 470111)
(1 1 1 0 1 1 3 5 41 37 7 5 250 515 9 0 2 13 566 44053 174 9371 401689 66970)
(1 1 1 0 2 5 4 1 36 1 21 3 106 4 813 542 116 197 19 949 187929 24 6 52)
(0 0 1 1 2 6 3 1 2 0 15 1010 50 30 13 51 15183 0 13328 1885 2 3 2787 1425)
(1 0 2 1 1 2 1 22 0 25 81 0 11 0 113 4975 177 2 15989 12 90275 186 7 2619)
(1 0 0 3 1 3 3 2 7 2 21 957 127 1055 1364 6 15462 2 40 39 16 298275 2985 762)
(0 0 1 1 7 1 2 1 1 200 256 1 1 1412 3913 0 61 1 355 0 4 25 2 292057)
(0 1 0 1 2 5 2 3 0 44 13 2 3 423 2744 381 689 233 260 1324 49733 280 14384 626)