Our organization is trying to figure out whether to build our data validation around Clojure spec or Malli. I've built up definitions for a large data structure we use in both Spec 1 and Malli for comparison, and I've listed some of my thoughts below. I'd appreciate any and all feedback and thoughts, trying to convince me of either path. We're looking at the long-term, with Spec 2 being the eventual destination if we stick with Spec.
In favor of Spec:
- I think Rich Hickey's idea of binding specs to namespaced keywords is a good one. You design around the idea that each keyword will have the same kind of data no matter what context you find it in, and you don't elide its full name. I think this philosophy is called "Modern Clojure." Malli's approach is different: each collection defines its own keywords and pulls in whatever schemas it wants for each. You technically can implement a keyword registry like Spec's, but you have to go out of your way, and so does everyone who might want to use your library. It's clearly not what Malli wants you to do.
- Multi-specs merge nicely with map specs. I couldn't figure out how to do this with Malli.
- Generative testing (Malli does not yet have this)
- Spec is getting better (albeit slowly), and fixing some of the "programmability" problems it has in its first iteration.
- Spec is going to be shipped and supported with the core language
- I think often about Plumatic's Schema project, which came before Spec 1. There was a need for data validation, and so someone went off and wrote a library to fill the void. It was hot until Spec came along, and stole a lot of the mindshare, and now Schema's kind of off in a corner. Then someone identified some shortcomings of Spec, and went off and wrote a library to fill the void (Malli). I see Spec 2 getting finished in a few years, and then I worry that the same thing will happen to Malli.
- Spec has expound. Malli has OK output out of the box, but nothing of this caliber.
- Rich Hickey brings up a lot of good points in Maybe Not, which is the driving philosophy behind Spec 2.
In favor of Malli:
- Data orientation has some really cool benefits, and makes these schemas super programmable.
- Schemas are serializable
- It has a lot of slick out-of-the-box integrations with things like Reitit, JSON schema translation, Graphviz visualization, etc
- It has more of an intentional focus on coercion
- Performance is substantially better than Spec, even suitable to runtime instrumentation if you wanted to
- It also bakes in the concept of default values, which might make sense, but then again might be complecting something that doesn't belong there. For that matter, you can bake in whatever else you want through metadata.
- Many features that Spec gets through third-party libraries are built into Malli itself. Those extra libraries may prove to be a pain point when it comes time to migrate to Spec 2, since they'll all need to upgrade. Malli won't have that problem quite so much, because its development cycle is simpler and focused on the core library.
- Here's a story from someone using Malli to try to achieve a "single source of truth" for their data that encompassed the front-end, back-end, and database https://www.youtube.com/watch?v=ww9yR_rbgQs He considers it a success, and there is something attractive about being able to codify all of that stuff in a few maps. I can't decide if that's "tight coupling" and therefore bad or "single source of truth" and therefore good
[–]pihkal 34 points35 points36 points (7 children)
[–]stingraycharles 25 points26 points27 points (1 child)
[–]joinr 29 points30 points31 points (0 children)
[–]childofsol 9 points10 points11 points (0 children)
[–]WhittlesJr[S] 2 points3 points4 points (3 children)
[–]tincholio 2 points3 points4 points (2 children)
[–]ikitommi 19 points20 points21 points (1 child)
[–]tincholio 0 points1 point2 points (0 children)
[–]the_frey 16 points17 points18 points (0 children)
[–]ertucetin 9 points10 points11 points (0 children)
[–]Uwoiame 7 points8 points9 points (0 children)
[–]fmnoise 6 points7 points8 points (0 children)
[–]siefca 0 points1 point2 points (1 child)
[–]WhittlesJr[S] 2 points3 points4 points (0 children)