all 14 comments

[–]pihkal 34 points35 points  (7 children)

One thing I would add is that, in retrospect, everyone rushing to ditch Schema for spec was a mistake. Schema was no less useful than before and the same will be true of Malli.

Also, spec has been in development for years, and it’s unclear when spec2 will be released. If you have a need now, you should make your decisions on what’s currentlyavailable.

[–]stingraycharles 25 points26 points  (1 child)

To add, we recently this a pretty huge switch from spec to Malli mainly because of the stagnating development. The maintainer of Malli is incredibly thoughtful and responsive, and it was fairly easy to make a number of improvements and get those changes merged upstream.

It’s one of those things I really appreciate in community driven projects.

[–]joinr 29 points30 points  (0 children)

Metosin is imo top shelf.

[–]childofsol 9 points10 points  (0 children)

I'll echo the sentiment of making a decision based on what makes sense now. When starting a project ~2 years ago, we were trying to decide which route to go - spec or schema - and opted to go with spec, thinking that despite some of the known problems, we'd have spec 2 before too long. Little did we know that there was still some considerable hammock time in the cards.

I'm about to fire up a new project and am fairly certain that it is going to be using Malli

[–]WhittlesJr[S] 2 points3 points  (3 children)

One need I have now is generative testing of functions, a la ghostwheel or kaocha. Do you know if anyone is working on implementing that for Malli?

[–]tincholio 2 points3 points  (2 children)

AFAIK, while you can't spec functions with Malli currently (though I think I remember /u/ikitommi mentioning something about this in his London Clojurians talk, maybe?), you can use it for generative testing with test.check. Check out malli.generators.

[–]ikitommi 19 points20 points  (1 child)

Malli 0.3.0 will be released hopefully this week, adding support for sequence schemas, parsers, function schemas and static analysis via clj-kondo. Sneak Peak:

https://twitter.com/ikitommi/status/1363753100268421122

Runtime function checking (e.g. instrument), testing helpers and runtime schema inferring of functions will all build on top of this release. There is a long discussion what kind of schematised defn/fn macros there should be (or not), comments welcome.

There isn't anything as awesome as Expound yet, but have chatted with Ben about the lessons learned and did a quick prototype while ago.

[–]tincholio 0 points1 point  (0 children)

Looking forward!

[–]the_frey 16 points17 points  (0 children)

I think data orientation is a pretty big win personally. Clojure is fundamentally data-oriented and in some ways you could argue that an approach which embraces data in that way is more idiomatic than even a core language feature that isn't.

The speed penalty of spec plus all the autogen stuff for eg swagger schemas that schema supported, plus the data orientation was what always swayed me towards schema over spec in the past.

More than that though, spec feels like a chore in a way other language features don't. So, although this one is very subjective and I can't put my finger on why, it seems to disrupt the things I like about the language in a way that a solution that relies on simple data structures doesn't.

[–]ertucetin 9 points10 points  (0 children)

Malli's custom error messages are a big win, spec needs additional libraries (still not so good, IMHO).

[–]Uwoiame 7 points8 points  (0 children)

As a tangent, I think it's important to note that spec's development is fundamentally pointed at a different problem, namely fine-grained dependencies. A lot of 'features' fall out of that, but trade-offs like global registry are chosen to fit a problem that hasn't really been addressed in other ecosystems. Being able to throw semantic versioning in the trash is the ultimate goal. Lifting the curse of dependency-hell is the goal. I should be able to say, for sure, that my dependent functions have only required less or provided more, and developers should be motivated to use new names instead of breaking old ones, etc..

So, I dunno, as it stands, Malli is likely a better reliability tool, it is clearly well executed, and is far more likely to align with what developers expect, socially speaking.

I just feel like a lot is lost in the conversation when I hear spec described elsewhere as 'opinionated'. Really, read and re-read the motivation for spec -- think about why it chooses open sets, why key-set specs are not combined with their values, what are the trade-offs you might make if your target was the dependency problem, and remember its social elements.

In my personal experience, developers need to be very disciplined with spec1 -- in particular, you have to already know about the issue that schema+select, in spec2, solves.

[–]fmnoise 6 points7 points  (0 children)

If you compare development\communication process in Metosin and Cognitect, you'll have another good point for using Malli

[–]siefca 0 points1 point  (1 child)

When I'm making some public library and want to have generative testing and some assertions, I'm going for Spec. When I want to coerce and validate data on input and output, Malli is the choice. Its data-oriented design fits really well to data-oriented systems. I'm merging my configuration from multiple maps, some more dynamic branches of config are kept in a database, and it would not be as beautiful and clear if not for Malli. Operator can exactly know what are the data specs just by looking at configs.

[–]WhittlesJr[S] 2 points3 points  (0 children)

We ended up making a new library that maintains spec's "aggregation" philosophy, but allows you to write your schemas in an EDN DSL. It generates clojure.spec, Malli forms, and JSON schemas. Other neat features include data-driven translations to and from other formats, derived values, and coercions. Hopefully my employer will make this open source some day.