clojure-spec

About: http://clojure.org/about/spec Guide: http://clojure.org/guides/spec API: https://clojure.github.io/spec.alpha/clojure.spec.alpha-api.html
Jim Newton 2020-10-05T07:58:09.055600Z

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?

Jim Newton 2020-10-05T08:01:29.056100Z

Is s/valid? side-effect free assuming the given pattern is side-effect free?

Jim Newton 2020-10-05T08:02:22.056800Z

Under which situations might s/valid? throw an exception? Do I need to wrap calls in try/catch ?

alexmiller 2020-10-05T13:05:36.063700Z

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

✔️ 1
Jim Newton 2020-10-05T13:17:40.065800Z

Is there a predicate I can use to know whether a given form is a valid "symbolic spec" ?

Jim Newton 2020-10-05T13:21:44.066400Z

Am I correct that s/valid? will throw an error if you give it an invalid symbolic spec?

alexmiller 2020-10-05T13:43:00.066700Z

I think s/spec will either give you a spec instance or an error

✔️ 1
alexmiller 2020-10-05T13:43:06.066900Z

s/valid? should do the same

Jim Newton 2020-10-05T13:44:30.068200Z

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.

Jim Newton 2020-10-05T13:45:58.069200Z

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...

➕ 1
alexmiller 2020-10-05T14:52:47.070Z

yes

Jim Newton 2020-10-05T15:32:48.070800Z

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?

alexmiller 2020-10-05T15:39:59.072Z

spec 2 is a bit better in this area (but is not ready for use yet)

vlaaad 2020-10-05T15:41:50.072200Z

#(contains? (clojure.spec.alpha/registry) %)

alexmiller 2020-10-05T15:49:03.072600Z

that's not what he's asking for afaict

Jim Newton 2020-10-05T15:59:10.073600Z

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?.

Jim Newton 2020-10-05T15:59:28.074Z

I suppose my first implementation doesn't to need to verify its values, just trust the caller, and let spec sort it out.

Jim Newton 2020-10-05T16:02:14.074500Z

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)

borkdude 2020-10-05T16:02:34.074700Z

symbols are used for fdefs

alexmiller 2020-10-05T16:59:00.075500Z

s/valid? takes spec names, spec forms, and spec objects - there is no method that validates all of those

✔️ 1