Fork me on GitHub
#clojure-spec
<
2017-01-01
>
tianshu11:01:11

does clojure.spec.test/instrument support check :ret and :fn for common function call?

tianshu11:01:46

currently it seems only work for test.check.

settinghead16:01:00

I noticed spec tolerates ambiguity (say (s/cat :first (s/* number?) :second (s/* number?)) can interpret [1 2 3] in 4 different ways, but it returns the first way it could find). is there any way to disallow ambiguity?

english16:01:12

@doglooksgood from the spec guide: "Note that the :ret and :fn specs are not checked with instrumentation as validating the implementation should occur at testing time."

mingp18:01:24

Those of you who use a lot of spec, what would you say to concerns that spec makes you code a certain way to be able to work with it, e.g. namespaced keywords for map keys? This is something that has worried me and made me hesitant to start using spec, but of course I say this as someone who hasn't used it, so what would those of you who have say?

mingp18:01:34

Something else I've been wondering. To what extent are you all using function specs vs explicit conform? Do you leave both/either on in production?

notanon18:01:41

@mingp what is the concern with namespaced keywords?

mingp18:01:02

My concern is, more broadly speaking, that spec expects me to code a certain way to be able to work with it. In the specific case of map keys, I'm normally in the habit of using regular keywords, but spec would work best if I switch to namespaced keywords instead.

mingp18:01:24

Again, I say this as not an actual user, so I'm trying to ask actual users if they believe these concerns are valid and if I should worry about them.

notanon18:01:46

well you can still use unqualified keys, it's fully supported

notanon18:01:31

the reason for namespaced keywords is just because specs are global, and so must have unique names

sveri18:01:44

I am not sure if thats a good approach, but, what I do is to use namespaced keywords for my definitions and unqualified names for the maps like (s/def ::foo-map (s/keys :req-un [::bar-key ::baz-key]))

notanon18:01:45

otherwise you wouldnt be able to reuse specs so easily

mingp18:01:39

More generally speaking, would you say spec has/hasn't constrained how you code Clojure?

notanon18:01:39

sveri's example is a good example of a compromise, ::foo-map can be re-used all across the app

notanon18:01:54

the only downside is that ::bar-key and ::bas-key will not be self-describing but... that's probably not going to be an issue for most use cases

notanon18:01:15

@mingp i don't see it constraining me personally. it's just a name

mingp18:01:57

That's good to hear. Thanks for that.

seancorfield19:01:43

Note that you can use namespace qualifiers on your :req-un keys to distinguish between different uses of the "same name".

seancorfield19:01:25

(s/keys :req-un [:foo/id]) is still the unqualified :id in the map but it uses the (qualified) :foo/id spec.

seancorfield19:01:01

So while ::id would be the same spec for all :id fields, :foo/id and :bar/id can be distinct :id specs.

joshjones20:01:48

@mingp As sean just said, just to be clear -- spec totally works with unqualified map keys. What's required to be namespace qualified are the keywords that name specs themselves.

notanon20:01:53

a subtle, but important difference. said another way (because it's subtle) only the specs themselves need to be namespaced qualified. the data they're spec'ing does not need to be qualified.

Alex Miller (Clojure team)22:01:20

spec would like to encourage you to work with maps with qualified keywords, but will support you to a limited degree if you can’t/don’t want to.

Alex Miller (Clojure team)22:01:56

from my own work with using specs while developing new code, I have found it has made me more likely to break out predicates and helper functions about my data (which has made the code better)

notanon22:01:36

I think I've heard or read that the fully qualified keys will make your data 'self-describing' but I really don't understand what that is buying me

potetm22:01:33

@notanon You get validation on keys you might not even know exist, because they're in a global registry.

potetm22:01:55

That's only possible because they're in a global registry. And to form a global registry, you need keys that are globally unique.

notanon22:01:59

hm. i don't think i get that, if I conform or validate based on a spec i've defined, i wouldnt have told it the 'keys i dont know about' are of this spec. and of course i might not want it conform/validate keys i didn't ask it to

Alex Miller (Clojure team)23:01:42

s/keys will validate all qualified keys in the map based on the matching spec in the registry

Alex Miller (Clojure team)23:01:23

we’re suggesting that you should want this :)

Alex Miller (Clojure team)23:01:45

this may seem weird, but it’s a key enabler for the kind of evolution Rich talked about in his Conj keynote https://youtu.be/oyLBGkS5ICk where you are “growing” a system over time

notanon23:01:52

yeah that makes sense. if i add a key later, it will automatically be validated without me updating the spec

notanon23:01:40

i guess if i just wanted to validate the presence of keys (only presence) i wouldn't use s/keys. not to mention that i don't think that would be very useful

Alex Miller (Clojure team)23:01:46

yes, something like #(every? #{:foo :bar} (keys %))