The argument that existence of specs provided to s/keys can only be checked at runtime is false.
The argument that that recursive specs are impossible if existence of specs provided to s/keys was checked at compile time is also false. The usecase for libraries is not convincing: If the libraries author states "the map has to have a key K" nobody can spec K further since that would be a race condition among consumers (who s/defs K first?). Requiring the libraries author to declare K as any? would at least require him to decide and convey his intent. The argument that not checking a value associated with a key is corresponding to a guding design principle of map specs being based on a keyset is not stating enough to justify discussed behavior. The utility of knowing that a keyset is present is close to none, which should be the main reasons why s/keys validates values. Again: Saying "A map that has a key called ::foo" is pretty pointless in Clojure. If every map in every Clojure program I wrote had a key ::foo they would all produce the exact same results as if they didn't and I bet yours would, too. Prototyping is indeed a bit more easy if one does not have to to declare every spec used in a s/keys. However, that is particularly damning if you forget to add that spec later or mistype its name when doing so. Which happens, and which is why I'm unhappy with this design letting such typical human errors pass compilation. It would also help my prototyping needs if I could reference symbols that are not declared, but I prefer the compiler errors before going live. On Saturday, October 7, 2017 at 12:01:34 AM UTC+2, Sean Corfield wrote: > > As one of the (apparently pretty uncommon) users who actually does happily > define s/keys specs without correspondingly speccing the leaves as an > "incrementally lock down/validate" approach, I wouldn't be too upset if I > lost that ability and it started throwing an error. I mean it throws an > error if I go to generate it anyway. > > > > **puts hand up!** > > > > I don’t want to have to write (s/def ::some-key any?) all over the place > as I’m developing specs, just to satisfy an overly eager checker (in my > mind). Worse, since the check would need to be deferred until validation > time, as Beau notes, the omission of an “any?” key spec might not even show > up until much further down the line. > > > > To me, this default behavior of silently not checking the _*value*_ > associated with a _*key*_ is in keeping with the design principles of > spec which focus on maps being based on a *key set*, while offering > functions to allow you to optionally check values. > > > > Sean Corfield -- (970) FOR-SEAN -- (904) 302-SEAN > An Architect's View -- http://corfield.org/ > > "If you're not annoying somebody, you're not really alive." > -- Margaret Atwood > > > ------------------------------ > *From:* clo...@googlegroups.com <javascript:> <clo...@googlegroups.com > <javascript:>> on behalf of Beau Fabry <imf...@gmail.com <javascript:>> > *Sent:* Friday, October 6, 2017 9:10:36 AM > *To:* Clojure > *Subject:* Re: [core.spec] Stricter map validations? > > A use case that comes to mind is a system/library that specifies the > structure of some inputs/outputs, but lets users/consumers (optionally) > specify further validation of the leaves. I suppose that would be possible > with (s/def ::foo any?) but you'd have to be a bit more careful about load > order. The other use case (which is mine) is I'm just lazy and only want to > write out broad strokes specs sometimes without getting into the nitty > gritty. > > If s/keys were to validate that the keys it's provided have specs it would > have to do it at validation time, so you wouldn't get the error until > something was actually validated against that key spec. Trying to do it at > definition time would break recursive specs. > > As one of the (apparently pretty uncommon) users who actually does happily > define s/keys specs without correspondingly speccing the leaves as an > "incrementally lock down/validate" approach, I wouldn't be too upset if I > lost that ability and it started throwing an error. I mean it throws an > error if I go to generate it anyway. > > On Friday, October 6, 2017 at 8:58:38 AM UTC-7, Leon Grapenthin wrote: >> >> Thanks, Beau. >> >> I am still interested why this default behavior has been chosen. It >> doesn't seem like a reasonable trade-off at this point. >> >> It enables me to say: "The map must have this key", without specifying >> how the data mapped to it will look like. >> >> If I ever wanted to do that, I could as well spec that key with "any?". >> >> What are other benefits? They must justify the expense of likely runtime >> errors. >> >> >> On Friday, October 6, 2017 at 5:34:16 PM UTC+2, Beau Fabry wrote: >>> >>> Leon, perhaps you could add this code to your test suite? >>> >>> boot.user=> (let [kws (atom #{})] >>> #_=> (clojure.walk/postwalk (fn [x] (when (qualified-keyword? >>> x) (swap! kws conj x)) x) (map s/form (vals (s/registry)))) >>> (clojure.set/difference @kws (set (keys (s/registry)))) >>> #_=> ) >>> #{:clojure.spec.alpha/v :clojure.spec.alpha/k} >>> boot.user=> >>> >>> On Friday, October 6, 2017 at 5:56:29 AM UTC-7, Leon Grapenthin wrote: >>>> >>>> Open maps/specs are fine. >>>> >>>> s/keys supporting unregistered specs are not. >>>> >>>> At least to me. I just fixed two more bugs in production that were >>>> would not have happened. >>>> >>>> What are the supposed benefits of this feature? >>>> >>>> I can only infer "being able to require keys without their spec being >>>> known" which is a usecase I had exactly 0.00% of the time so far. >>>> >>>> Anything I have missed? >>>> >>>> Kind regards, >>>> Leon. >>>> >>>> >>>> On Wednesday, October 4, 2017 at 7:05:29 PM UTC+2, Beau Fabry wrote: >>>>> >>>>> Seems like that's the reasonable place to check it, otherwise you're >>>>> forced into an ordering for your specs and cannot write recursive strict >>>>> map specs. >>>>> >>>>> On Wednesday, October 4, 2017 at 8:59:59 AM UTC-7, Yuri Govorushchenko >>>>> wrote: >>>>>> >>>>>> Thanks. This approach is also different from the macro because it >>>>>> will check specs existence at the validation time, not at the s/def call. >>>>>> >>>>>> On Wednesday, October 4, 2017 at 4:18:16 PM UTC+3, Moritz Ulrich >>>>>> wrote: >>>>>>> >>>>>>> Yuri Govorushchenko <yuri....@gmail.com> writes: >>>>>>> >>>>>>> > Thank you the pointers! So far I ended up with writing a small >>>>>>> `map` macro >>>>>>> > which is similar to `s/keys` but checks that keys are already in >>>>>>> the >>>>>>> > registry: >>>>>>> https://gist.github.com/metametadata/5f600e20e0e9b0ce6bce146c6db429e2 >>>>>>> >>>>>>> Note that you can simply combine a custom predicate and `s/keys` in >>>>>>> clojure.spec to verify that all keys in a given map have a >>>>>>> underlying >>>>>>> spec: >>>>>>> >>>>>>> ``` >>>>>>> (s/def ::whatever (s/and (s/keys ...) >>>>>>> #(every? keyword? (keys %)) >>>>>>> #(every? (comp boolean s/get-spec) (keys >>>>>>> %)) ) >>>>>>> ``` >>>>>>> >>>>>> -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clo...@googlegroups.com <javascript:> > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+u...@googlegroups.com <javascript:> > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+u...@googlegroups.com <javascript:>. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.