I think Rich would claim that spec forms are data :)
But spec 2 already has an alternative map-based data format (which is heavily subject to change)
That thought has occurred to me as well... I think we're conditioned to think that "data" means "EDN," but quickly forget that this is a LISP.
I've been using clojure a lot lately to transform or combine data (usually from one or more REST endpoints) from one form into another. I am using spec the same way I would have used case classes in scala or json schemas -- to validate the input and output (often exactly that, with :pre
and :post
conditions). I'm assuming that I'm staying away from anything controversial and that it will be easy to change these to spec2. But that may be an incorrect assumption. I'm sticking with the "official" one only because I'm so new (I really only use Clojure one or two days a week) that I'm not experienced enough to judge third-party libraries. I'm just trusting the manufacturer here.
@eamonn.sullivan The clojure.spec.alpha lib will be around probably forever, so even if spec2 gets bundled with core, you will still be able to use the old one
The main difference in spec1 and spec2 is how s/keys
works, this will be replaced with s/select
(this is probably an over-simplification as I haven't been following spec2 for a while - I would love to get some updates!)
regarding the discussion about the strict separation of coercion & validation: are there any public non-trivial repos/projects showcasing this principle in practice (e.g. coercing and validating http requests/parameters etc)?
https://github.com/clojure/spec-alpha2/wiki/Differences-from-spec.alpha is the overview
s/keys actually works the same for now but will be superseded by s/schema and s/select https://github.com/clojure/spec-alpha2/wiki/Schema-and-select
I fear we are in another one of those situations where the non-trivial codebases using Spec heavily are all in-house/proprietary:
Clojure source 348 files 87710 total loc,
3532 fns, 896 of which are private,
556 vars, 29 macros, 93 atoms,
849 specs, 33 function specs.
Clojure tests 378 files 23192 total loc,
4 specs, 1 function specs.
That's a quick break down of stats for our codebase at work.We decided to go with spec, by the way. We're betting that the number and quality of libraries in spec's orbit will explode when the official release drops, seeing as it will be so much easier to interact with specs programmatically. And regardless of the ecosystem of the future, it has what we need right now. Malli is doubtless pushing the state of the art forward, but I have no doubt that many people will want to incorporate features and discoveries Metosin makes along the way into a spec-based architecture.
(s/form (s/keys* :opt-un [:clojure.core.specs.alpha/exclude :clojure.core.specs.alpha/only :clojure.core.specs.alpha/rename]))
=> (clojure.spec.alpha/&
(clojure.spec.alpha/*
(clojure.spec.alpha/cat
:clojure.spec.alpha/k
clojure.core/keyword?
:clojure.spec.alpha/v
clojure.core/any?))
:clojure.spec.alpha/kvs->map
mspec__2546__auto__)
How do I introspect s/keys*
spec? form says nothing about actual keys...found it...
(-> (s/keys* :opt-un [:clojure.core.specs.alpha/exclude :clojure.core.specs.alpha/only :clojure.core.specs.alpha/rename]) :ps second s/form)
=> (clojure.spec.alpha/keys
:opt-un
[:clojure.core.specs.alpha/exclude :clojure.core.specs.alpha/only :clojure.core.specs.alpha/rename])
that looks very unreliable though... can I rely on regex ops data shape?what you need are specs for spec forms themselves - then you can conform the spec and get a map (you can also modify that map and s/unform it back to a spec form). some work on this in https://clojure.atlassian.net/browse/CLJ-2112 (but likely we'll never actually finish this as spec 2 will make it unnecessary)
Well, the form of s/keys* has no useful information at all if you look at the output
I.e. there are no mentions of actual expected keys
yeah, this has to do with the mixture of symbol / object in spec 1 which is almost entirely cleaned up in spec 2