I'm not a spec user, but I have a few questions about the API. Is it true that spec designates certain symbols as patterns? How can I know whether a given symbol designates a spec pattern? As I understand, given such a symbol, I can call (s/valid? pattern-designator some-value)
to determine whether a given value conforms to the pattern. Are such pattern designators always available globally? or can the be defined lexically and thus be invisible to other applications?
Is s/valid?
side-effect free assuming the given pattern is side-effect free?
Under which situations might s/valid?
throw an exception? Do I need to wrap calls in try/catch
?
By “pattern”, I assume you mean “symbolic spec”. Specs have both a spec form (comprised of keyword names, list forms, sets, functions, etc) and a compiled instance form. Spec forms refer to macros that expand to code that emits spec instances. The details of this are quite a bit different in spec 1 and 2. But in both cases the spec forms are available globally as they are defined by macros. s/valid? does not have side effects of its own. s/valid? itself won’t throw but if it includes a predicate, that might throw on a bad input
Is there a predicate I can use to know whether a given form is a valid "symbolic spec" ?
Am I correct that s/valid?
will throw an error if you give it an invalid symbolic spec?
I think s/spec will either give you a spec instance or an error
s/valid? should do the same
that's reasonable, yes. So It could be nice if my application could ask spec whether the given spec instance is valid or not, before putting it in a place where at some time in the future when s/valid?
is eventually called, spec will throw an error.
OH, am I correct in assuming that s/valid?
checks whether the given data matches the spec? i.e., it does not validate the spec, but rather validates the data...
yes
so which function should I use to detect whether a candidate given to my by the function who called me, is a valid symbolic spec?
spec 2 is a bit better in this area (but is not ready for use yet)
#(contains? (clojure.spec.alpha/registry) %)
that's not what he's asking for afaict
Without knowing spec, it is hard to know really what I'm asking for. But Id like to know whether what I have in variable x
is something I can pass as the first argument of s/valid?
.
I suppose my first implementation doesn't to need to verify its values, just trust the caller, and let spec sort it out.
looks like everything in that registry is either symbol or a keyword. (distinct( map (fn [x] (or (symbol? x) (keyword? x))) (keys (clojure.spec.alpha/registry))))
returns (true)
symbols are used for fdefs
s/valid? takes spec names, spec forms, and spec objects - there is no method that validates all of those