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
alexmiller 2021-02-23T00:04:42.055400Z

I think Rich would claim that spec forms are data :)

1🧠1☝️
alexmiller 2021-02-23T00:05:34.056600Z

But spec 2 already has an alternative map-based data format (which is heavily subject to change)

Alex Whitt 2021-02-23T00:09:43.056800Z

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.

mpenet 2021-02-23T09:45:56.057800Z

spec is generally very opinionated, but once you "get" the design choices it's hard to be in disagreement with it. It fits quite well with datomic, "Maximal Graph" & co approach to dealing with data, which imho is spot on (I am not a datomic or pathom user but I agree with the general ideas). Right now it's also quite bare bones but there are a few libraries that fill the important gaps (coercion, error messages, etc). Then for me at least spec2 would fix most of the important problems I have with v1 (mostly schema+select, or whatever these will be called), but even without spec1 is very usable. Most of the problems stated about spec 1 imho are very often overblown or just misunderstanding on how to use spec or its goals. But I get the frustration of malli authors who wanted spec2 now (I do too, but I rather have something carefully designed than a rushed draft) and the amount of work they poor into malli earns respect. Personally I do not agree with some of their design choices and most importantly the fact this will cause yet more fragmentation in that space. I would rather have had all that fire power put in spec libraries. I also had to deal with code bases that invested in spec-tools and broke some teeth in the process, so I prefer to be very conservative when I choose a library to fill that spot now.

mpenet 2021-02-23T09:50:36.058Z

about closed specs & data for me these are quite minor issues (if at all), I had to generate specs from another dsl on work I did recently and it's not a big deal at all. For more advanced composition I can't remember a case where i was blocked by the current api, in extreme cases you can rely on eval/macros to get to what you want but it's extremely rare in my experience at least. That said if spec2 improves that, great. For closed specs it's the same, writing a strict-keys version of s/keys is quite easy a naive version with poor error reporting is a couple of lines and a more involved one with nice error messages more work but it's under 50 loc

mpenet 2021-02-23T09:53:51.058500Z

having multiple choices might be good, that's could be a sign we have a "healthy" community

borkdude 2021-02-23T10:47:38.059300Z

About the data driven nature of malli vs spec: I think it's fair to say that malli schemas are a better fit if you want to have a programmatic way of creating/changing schemas (in spec you end up with macros for this usually) and when you want to have (de)serialization of your schemas. That's not to say that you can't do this with spec, but the UX of malli is probably better for this kind of use.

Eamonn Sullivan 2021-02-23T10:52:02.063400Z

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.

borkdude 2021-02-23T10:57:05.064100Z

@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

borkdude 2021-02-23T10:58:19.065100Z

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!)

lassemaatta 2021-02-23T11:32:36.066900Z

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

alexmiller 2021-02-23T13:11:01.067200Z

https://github.com/clojure/spec-alpha2/wiki/Differences-from-spec.alpha is the overview

alexmiller 2021-02-23T13:11:29.067400Z

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

2021-02-23T16:06:06.067800Z

I'm glad y'all are taking your time. It's worth it.

seancorfield 2021-02-23T17:35:34.068500Z

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.

Alex Whitt 2021-02-23T18:29:55.071500Z

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.

6👍
vlaaad 2021-02-23T21:52:30.073800Z

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

vlaaad 2021-02-23T21:55:35.074600Z

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?

alexmiller 2021-02-23T21:57:37.076Z

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)

vlaaad 2021-02-23T22:10:16.076100Z

Well, the form of s/keys* has no useful information at all if you look at the output

vlaaad 2021-02-23T22:11:17.076300Z

I.e. there are no mentions of actual expected keys

alexmiller 2021-02-23T22:51:08.077200Z

yeah, this has to do with the mixture of symbol / object in spec 1 which is almost entirely cleaned up in spec 2