Fork me on GitHub
#clojure-spec
<
2017-09-19
>
stathissideris11:09:18

why does this result in the function to be called several times?

(s/valid? (s/fspec :args (s/cat))
                          (fn []
                            (println 'foo)))

stathissideris11:09:58

21 times in fact

gfredericks11:09:05

I think it's quickchecking your function to make sure it matches the spec

stathissideris12:09:51

ok, is there any way to say that it’s fine if the function throws an exception?

stathissideris12:09:22

because:

(s/valid? (s/fspec :args (s/cat))
                          (fn []
                            (throw (ex-info "foo"))))

Alex Miller (Clojure team)12:09:39

no, exceptions should be … exceptional

danielneal12:09:27

Congrats on the 1.9 beta release! I'm just wondering how much of clojure is planned to be specced? I'm guessing it's just the macros - or are there plans to spec clojure core functions as well?

Alex Miller (Clojure team)12:09:03

tbd both from a short-term and long-term perspective

Alex Miller (Clojure team)12:09:20

there are several categories of fns that can’t currently be instrumented (protocols, multimethods, primitive fns, inline fns) so that limits some things

Alex Miller (Clojure team)12:09:57

I’ve worked on others and I think it is valuable to have them. it is also pretty tricky to spec some of them, esp the higher order stuff

danielneal12:09:13

yeah that makes sense

danielneal12:09:58

so "everything" - probably out of scope - but there are plans over the long term to spec what would be useful, including the functions

Alex Miller (Clojure team)12:09:39

I would hesitantly say yes as there are also performance things to be aware of when you load a large number of specs

Alex Miller (Clojure team)12:09:05

right now, the core.specs.alpha has only macro specs in it and that’s loaded implicitly on first macro expansion

Alex Miller (Clojure team)12:09:30

I think for fns, we may want to put those in a separate ns that you explicitly load if you want to instrument core

danielneal12:09:44

ah I see that makes sense

Alex Miller (Clojure team)12:09:26

since core.specs.alpha is a separate lib, this is something that can evolve and be released in between clojure releases too. so if it doesn’t get done for 1.9 ga, can still make progress before the next major release

seancorfield15:09:32

@danieleneal I have almost everything spec'd in clojure.java.jdbc and run the test suite with it instrumentd -- it's quite an overhead. When I get to my desk I can get numbers.

seancorfield16:09:16

So I have rough numbers now: clojure.java.jdbc has about 600 assertions. Against 1.8 it takes about 30 seconds (about 14 seconds "real" time). Against 1.9 with instrumentation it takes about 100 seconds (about 70 seconds "real" time). @danieleneal /cc @alexmiller

Alex Miller (Clojure team)17:09:31

what does it take on 1.9 without instrumentation? :)

Alex Miller (Clojure team)17:09:50

comparing apples to orange juice there

seancorfield17:09:41

Let me just comment out the instrument call to check that...

seancorfield17:09:22

Pretty much identical. 1.8 looks a hair faster but I'd have to run the test suite a lot more times to be certain.

seancorfield17:09:58

And the 30/100 seconds above is "user" (cpu) time. The "real" time is elapsed.

jeaye19:09:34

Yeah, jdbc was heavy for me, when instrumenting as well. Much, much heavier than all of our intrumenting combined.

jeaye19:09:51

Had to disable it during development.

seancorfield19:09:48

@jeaye It has specs for all the public API and JDBC stuff tends to get called a lot in DB-centric apps 🙂 If you think it's doing something suspect in its specs that causes undue performance overhead, let me know.

richiardiandrea20:09:37

hello folks! is there somewhere a wrapper for passing spec keys directly to generate? I mean without the extra nested call to s/gen, ideally (somewhere/generate :my-ns/key)?

bfabry21:09:42

@richiardiandrea exercise?

boot.user=> (s/def ::foo integer?)
:boot.user/foo
boot.user=> (s/exercise ::foo 1)
([0 0])

jeaye22:09:59

@seancorfield Will do. I did end up looking, when I saw how long it was taking, and the specs seemed sane to me. It might be worth digging deeper, to see why these specific specs are taking so long. If I had to guess, it's the extensive usage of s/or and s/cat with s/*, wheras just about every spec we have is a s/keys or a clojure.core predicate.

seancorfield03:09:24

Good point. I might look at refactoring the specs to make them more efficient...