Your spec names need different namespaces, but your functions do not:
(s/def :catalog-a/type #{"a" "b" "c"}) (s/def :catalog-a/ref string?) (s/def :catalog-b/type #{:x :y :z}) (s/def :catalog-b/ref number?) Then you need to say that the keys are unqualified when they appear in the map for this function: (s/fdef get-product-from-catalog-a :args (s/keys :req-un [:catalog-a/type :catalog-a/ref] :ret any?) (s/fdef get-product-from-catalog-b :args (s/keys :req-un [:catalog-b/type :catalog-b/ref] :ret any?) In general clojure spec tighly binds key names in maps to spec names and it is very hard to separate them. This is a formal part of its rationale, expressed as "Map specs should be of keysets only" <http://clojure.org/about/spec#_map_specs_should_be_of_keysets_only>. There is a case I do not understand how to do well, where I want a specific function to accept a map with a specific specced key, but I want that key's value to conform to some strict subset of possible values as well. In essence, I want to "subclass" the key. The options I see are: 1. Make a different spec based on the parent spec but adding refinements, then make and spec adaptor functions which do nothing but change the key (and validate). I.e., do the respec dance before the code. 2. In the body of the function, call another function that accepts the spec as a value (rather than in a map), and refine the value there. Your outer function will still have to accept other values and handle them somehow (signal error, throw, whatever). Both of these are awkward when dealing with existing systems which to not consider specs to be of keysets only. In particular, we deal with a specification called FHIR <https://www.hl7.org/fhir/> whose type model allows "profiles", which are declared on an instance (e.g. a map would have a type key for the base type and optionally a "profiles" key which is any additional specs to which the map must conform). A profile is essentially a restriction of the instance's basic types (they can never extend) such that any profiled instance must always conform to the base type's spec. E.g. if a field is allowed to have values "a" and "b", the profile may say that field may only have "a". So in essence we want maps to potentially conform to multiple specs at once: the base spec which is the keys in the map, and a profile spec which uses the same keys but may add additional restrictions. I have not thought of a good way to express this in clojure.spec. On Thursday, November 17, 2016 at 10:54:18 AM UTC-6, damien....@gmail.com wrote: > > I forgot the :req-un. > > (s/fdef get-product-from-catalog-[a|b] > :args (s/keys :req-un [::type ::ref]) > :ret any?) > > > > -- 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.