Fork me on GitHub
#clojure-spec
<
2022-08-17
>
Stel Clementine17:08:57

Is dynamically redefining specs good practice? I want to check if certain values in a config map match values from another location in the config map so I'm using this function:

(s/def :nuzzle/author keyword?)
;; Dynamically redefine :nuzzle/author based on config
(defn redefine-author-spec [config]
  (s/def :nuzzle/author (s/and keyword? (-> config :nuzzle/author-registry keys set))))
It totally works for my use case but I'm wondering if this is something that is typically not recommended.

phronmophobic17:08:19

I couldn't find anything directly related, but it does seem to go against the spirit of an open system with global semantics: https://clojure.org/about/spec#_unify_specification_in_its_various_contexts > Specs for data structures, attribute values and functions should all be the same and live in a globally-namespaced directory. https://clojure.org/about/spec#_informational_vs_implementational > Invariably, people will try to use a specification system to detail implementation decisions, but they do so to their detriment. The best and most useful specs (and interfaces) are related to purely information aspects. Only information specs work over wires and across systems. We will always prioritize, and where there is a conflict, prefer, the information approach.

☝️ 1
👍 1
Alex Miller (Clojure team)18:08:00

I would not recommend it due to the redefinition, but dynamically creating a spec is not inherently bad and can be useful. I think my question then is whether this is really a spec or something weaker.

Alex Miller (Clojure team)18:08:33

you also don't necessarily have to put the spec in the registry

Alex Miller (Clojure team)18:08:26

that is, you could just use s/valid? on a spec you create and pass around

Alex Miller (Clojure team)18:08:54

(won't work when validating s/keys with namespaced keys)

Stel Clementine22:08:37

@U064X3EF3 That makes sense. I really just want the amazing bhb/expound error messages so I'm trying to shove stuff into specs that maybe shouldn't be there. I think I could use a local spec instead. Thank you!