This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-06-28
Channels
- # admin-announcements (2)
- # alda (5)
- # arachne (4)
- # beginners (49)
- # boot (92)
- # capetown (3)
- # cider (9)
- # cljs-dev (6)
- # cljs-edn (1)
- # cljsjs (29)
- # cljsrn (4)
- # clojure (65)
- # clojure-android (1)
- # clojure-berlin (2)
- # clojure-chicago (2)
- # clojure-gamedev (2)
- # clojure-greece (11)
- # clojure-india (1)
- # clojure-japan (1)
- # clojure-new-zealand (2)
- # clojure-quebec (2)
- # clojure-russia (49)
- # clojure-spec (73)
- # clojure-uk (38)
- # clojurescript (118)
- # clojutre (4)
- # community-development (17)
- # cursive (3)
- # data-science (1)
- # datascript (1)
- # datomic (17)
- # emacs (6)
- # euroclojure (2)
- # events (2)
- # immutant (30)
- # keechma (11)
- # leiningen (4)
- # luminus (2)
- # off-topic (19)
- # om (14)
- # onyx (28)
- # planck (9)
- # re-frame (11)
- # reagent (35)
- # ring-swagger (4)
- # schema (4)
- # slack-help (6)
- # spacemacs (2)
- # specter (11)
- # testing (4)
- # untangled (88)
- # utah-clojurians (2)
- # vim (2)
- # yada (9)
New favourite spec trick. Wrap your spec to generate warnings instead of erroring out.
(defn warn
"Throw warning if spec is invalid but always pass."
[spec]
(fn [x] (when-not (s/valid? spec x)
(js/console.warn (s/explain-str spec x) x))
x))
And now not. Turns out the stack trace from normal errors is more informative (cljs).
I have within one ns two different specs for :db/id
(one for data coming from datascript and one for datomic ids). How can I specify this in spec?
Is this the way to do this: https://gist.github.com/rauhs/3bf96b33f37f051859d5071cdde70148 ?
I guess I could just use vector?, but I'd like it ideally to generate lots of random Clojure things to go in the vector.
Similarly, what about a map where the keys can be anything but the vals are more restricted?
There is new support for this in next alpha
coll-of has many new options
Can now indicate the expected incoming type separately from the conformed and generated type
Also, Rich added s/merge
yesterday to create spec that merges multiple map-validating specs and will gen as you expect (union of keys)
@jannis in next alpha you will be able to do (s/coll-of int? :kind []) to indicate a vector of ints
@alexmiller: Awesome 🙂
When a spec is complicated and composed of many component specs, I'm having trouble figuring out, stylistically, which of those component specs to register to namespaced keys, versus just def'ing them to regular vars. Any tips on this?
It seems to me that when spec'ing a bunch of optional keywords for a function, to get good error messages I really want to be able to say "These are the only keys allowed in this map of optional keywords and values". Is there any way to do that?
generally, I think you should not def anything to a regular var
and you should register specs for all map attributes and for any major “types"
anything recursive will require registration at the recursion points
and you might want to register things at a finer granularity if you find it gives you more meaningful explain errors
re restricted key sets - no, this is intentionally not provided, but you can s/and a constraint like #(every? #{:allowed :keys :in :map} (keys %))
Thanks. Early on, I predicted that a lot of people would re-invent slightly different definitions of validating or conforming combined with assertions in the event of a failure, and I've been seeing that happen. Is something along the lines of assert-conform and assert-valid? likely to make it into a future alpha?
yes, there are likely to be a conform-ex and some kind of assert, but I don’t think those will be in next alpha
I've been wanting to add an extended :reason to certain specs, especially if they have strange interdependencies
If you look sideways at this you could see the possibility of specs with composable prose explanations
Super quick question: If I’m referencing a spec in another namespace, do I need to :require
that namespace too?
I’m finding the app runs fine in the REPL, but at compilation, it can’t resolve the specs.
Okay, I was afraid of that 😉
Thank you!
So, form-validation & clojure.spec, I assume people have tried it already, are there any writeups/snippets?
@bhauman: @kendall.buchanan I find it interesting that this can create an implicit dependency between namespaces that is not declared via the ns form, maybe for "good style" you should require the ns containing the spec even if you don't need to (technically)?
I’ll admit – I still find the coupling between specs and namespaces odd. Namespaced keywords seem to make sense when you’re trying to define a domain path, but sometimes those domain paths don’t match your namespace hierarchy. But Clojure basically says it has to.
Still struggling to understand it. But, seems fine.
@kendall.buchanan: you are aware that you don't have to use an existing namespace correct?
Yeah, totally, but I guess I’m struggling to see the established path forward.
> but sometimes those domain paths don’t match your namespace hierarchy
👍 (same struggle here)
In terms of dependency management, I think if people look at the way they did plumatic/schema or any add hoc type validation.
We've started defining a lot of our specs in a separate heirarchy. It's a bit early to tell how well that works but thus far it's been pretty useful in terms of reducing circular dependency issues, making specs equally usable in tests and code, etc.
@bhauman, would you recommend (or consider as a viable path) to always use domain-based keywords school/:type
and eschewing ::type
(contained in my.app.model.school
? Just ditching the latter pattern?
So that's one possibility, is to use ::type
but to place those definitions in a namespace that is a little descriptive of the domain model.
@angusiguess: Kind of like app.spec.school/type
? That’s more or less what I’ve done for objects that cut across many domains.
@kendall.buchanan: That's precisely what I do, including a namespace for more generic types.
Like
app.spec/uuid-str
or similar.Right.
Yeah, exactly what we’ve started doing.
Then if we have aggregates that our functions take we'll define them in the function's namespace.
And I think it works well. I guess I like the ::thing
syntax, for brevity, and realize it ties things up into the namespace. I guess we’re learning as we’re going, though.
(By the way, I have no proposed alternative, so not complaining. Just been a source of friction for me.)
Defining everything in-line bit us pretty quick.
Right, @angusiguess… which, I have to say, clojure.spec is what it claims: built for composability. I’ve been a heavy Schema user, and have to say, I’m getting more reuse out of spec by far.
Clojure 1.9.0-alpha8 is now out with lots and lots of spec updates https://groups.google.com/d/msg/clojure/vF3RuDWuX8I/pvn4IUuUAwAJ
Lots of new spec stuff in alpha 8 - conforming coll support, plus count/kind control, instrument can generate stubs, gen/spec overrides in instrument/test, merge keys specs