This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-06-19
Channels
- # beginners (17)
- # boot (7)
- # cider (1)
- # cljsrn (4)
- # clojure (22)
- # clojure-austin (19)
- # clojure-canada (1)
- # clojure-dusseldorf (1)
- # clojure-greece (3)
- # clojure-russia (19)
- # clojure-spec (46)
- # clojure-uk (23)
- # clojurescript (17)
- # core-async (7)
- # cursive (13)
- # dirac (66)
- # kekkonen (1)
- # lein-figwheel (2)
- # om (1)
- # onyx (2)
- # re-frame (1)
- # reagent (1)
- # specter (2)
You can compose any kind of spec with and
Note also that s/keys validates all keys in the map regardless of what's in req or opt
So you don't technically have to list them as opt keys
(s/fspec :args ... :ret ... :throws ...)
In clojure.spec, is there a way to associate custom generators with your own functions, the way that clojure.spec.gen/gen-for-pred
and gen-builtins
associate generators with various clojure.core functions?
cigitia: you can make a spec that has a particular generator associated with it using spec/with-gen
@gfredericks: Yes, though that requires either registering the spec returned by with-gen
under a keyword, or using with-gen
inline every time you use the function.
I’m wondering whether it’s possible to have generators when using functions directly—
Like how int?
has a generator even when you use int?
directly as a predicate, due to the way gen-for-pred
works.
I think you can say (def int? (spec/with-gen #(instance? Integer %) gen/large-integer))
I might be lying
There is more stuff coming in this area soon
@gfredericks: is :throws
discussed somewhere? I can’t find something about it.
akiel: no I just made it up
I was imagining an API that related to what you were asking about
@gfredericks: Yes that’s exactly what I’m after. @alexmiller What do you think about exception data specs? As far as I see it, exception data keys are not even documented normally.
We are not going to spec exceptions
You could of course create specs for the ex-info map keys and I can see that possibly useful in functions that receive ex-info data after an exception has happened (to generate user errors or error pages etc)
Do you think that the shape of the ex-data should be public API of a function or do you are more in line with Joshua Bloch: Effective Java Item 57: Use exceptions only for exceptional conditions were he suggests that exception should not be used for decision making.
Unless you're abusing it for performance :)
@alexmiller: sorry for asking further - yes public or yes not-public?
1. spec is not a type system 2. spec is primarily about specifying data and exceptions are not data, they are weird control flow operation in a language 3. specs for functions specify what valid argument data looks like, and given that valid argument data, what a valid result looks like, and that is how the generative stuff works, and in that model there is no place for exceptions
given a function F, if F throws E, to ensure correctness you want to look at all callers of F, and ensure that they handle E correctly, which is exactly the opposite of how the generative testing works (if I understand correctly)
@hiredman: in case API’s don’t use exceptions for control flow I’m with you. But than we don’t need ex-info
and ex-data
at all and should stop build API’s which put data into exceptions
Is there a way to validate that you have defined all namespaced keywords in the your spec definitions? And get a warning if some are missing?
hmmm ... so say compose a macro over spec/keys, capture the key args and and then warn if if the keys are not present in the registry? or were you thinking something else?
if you wanted to verify everything with a single call though it seems like you would have to parse the describe of each of the registry members
user=> (s/valid? (s/map-of #(if (and (keyword? %) (namespace %)) (contains? (s/registry) %) true) ::s/any) {:a 1})
true
user=> (s/valid? (s/map-of #(if (and (keyword? %) (namespace %)) (contains? (s/registry) %) true) ::s/any) {::a 1})
false
user=> (s/def ::a ::s/any)
:user/a
user=> (s/valid? (s/map-of #(if (and (keyword? %) (namespace %)) (contains? (s/registry) %) true) ::s/any) {::a 1})
true
user=>
cool yep, but was thinking of a different use case, where you are inspecting the self referential integrity of the registry itself
not sure I follow? that s/map-of spec will fail if given a map with namespaced keys that are not speced
you'd like ::foo to throw an error earlier then when you run the spec, basically, like clojure does with vars