> 1) Is there any way to ensure that the keys I used in `s/keys` have the associated specs defined?
I think you should be able to do this by writing a function that uses s/registry s/form and s/get-spec On Monday, October 2, 2017 at 8:37:31 AM UTC-7, Yuri Govorushchenko wrote: > > Hi! > > I have some noobie questions for which I couldn't google the compelling > answers. > > 1) Is there any way to ensure that the keys I used in `s/keys` have the > associated specs defined? At compile time or at least at runtime. Maybe via > an additional library? I could imagine a macro (smt. like `s/keys-strict` > or `s/map-pairs`, as maps can also be viewed as sets of spec'ed pairs) > which additionally checks that all keys have specs registered. I'm OK with > sacrificing some flexibility (e.g. being able to define key specs after map > specs, dynamically, etc.) in favour of more strictness. > > Motivation: I don't fully trust my map validation code when using > `core.spec`. `s/keys` doesn't require that the key has the spec registered > to validate its value. Although this may be flexible but in practice can > lead to errors. Specifically, it's quite easy to forget to create a spec > for a key, mistype it or forget to require the namespace in which key spec > is defined (e.g. if the common key specs reside in a dedicated ns): > > ``` > ; totally forgot to define a spec for ::foo > (s/def ::bar (s/keys :req [::foo])) > > ; fooo vs. foo typo > (s/def ::fooo string?) > (s/def ::bar (s/keys :req [::foo])) > > ; :common/foo vs. ::common/foo typo > (s/def ::bar (s/keys :req [:common/foo])) > > ; didn't require common.core ns (spec for :common.core/foo is not added to > global registry) > (s/def ::bar (s/keys :req [:common.core/foo])) > ``` > > These subtle mistakes can lead to map validations passing silently (as > long as keysets are correct). > > Related to this: there're feature requests for Cursive IDE which try to > address typing and reading mistakes related to keywords, e.g. > https://github.com/cursive-ide/cursive/issues/1846 and > https://github.com/cursive-ide/cursive/issues/1864. > > After using Schema for a while it's difficult to appreciate the way > `core.spec` defines it's own global registry which uses keywords instead of > using spec instances and good old variables, especially since Cursive IDE > has quite a nice support for variables already. But I think this is another > topic which was already discussed, e.g. in > https://groups.google.com/forum/#!topic/clojure/4jhSCZaFQFY ("Spec > without global registry?"). > > 2) What is the motivation for library having a "loose" default behaviour > of `s/keys` and no "strict" variant at all for spec-ing both keys and > values at the same tome? I think in majority of cases I'd need to spec both > keys and values of the map instead of only keys and would expect the > library to have built-in API for this. Maybe for the future references it > would be beneficial to add concrete code examples into motivation in the > core.spec guide ( > https://clojure.org/about/spec#_map_specs_should_be_of_keysets_only) > which would better illustrate the described benefits of the current lib > behaviour? > > Thanks. > -- 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.