haskellari/tree-diff

Extract ToExpr into a separate package

Closed this issue · 3 comments

lehins commented

It would be tremendously useful to split out the ToExpr type class together with Expr data type into a separate package.

It would allow libraries to define ToExpr instances with minimal set of transitive dependencies. tree-diff isn't exactly a lightweight package when it comes to dependencies

In other words libraries then would be able to define ToExpr instances by only depending on tree-diff-class, while test suites would depend on the full ctree-diff package

phadej commented

tree-diff dependency footprint is essentially aeson and prettyprinter. IMO it's not too heavy.

EDIT: And aeson dependency is more or less forced, as I want ToExpr (Vector a), ToExpr (HashMap k v), and ToExpr Value instances to exist. I doubt vector or unordered-containers will depend on tree-diff.

phadej commented

Thinking about this a bit more: I don't think we'll see an adoption of tree-diff-class on Hackage to justify this. People are hesitant to add QuickCheck instances (I think I'm only one who actually does that, and IIRC I got some unsatisfied-with-that reports e.g. when these depended on QuickCheck). I don't see people writing smallcheck instances, validity instances, nor hedgehog generators. Why would tree-diff be any different, after all it's yet another testing-aid lib? If you don't like orphan instances (which IMO are completely fine in test-suites), you should be able to use explicit conversion functions like hedgehog has explicit generators (toExpr @Expr = id!)

Until there is large-enough buy-in from library maintainers,which I don't expect to see, this won't happen.

The only success of "split class out of the it's main user" is hashable and unordered-containers. And still getting Hashable instances into the data defining libraries may be quite a chore. The split actually brings another set of problems, as people want to use hashable outside of its primary use-case (i.e. putting stuff into HashMap).

lehins commented

I don't see people writing smallcheck instances, validity instances, nor hedgehog generators.

Generation of test data is a bit different IMHO, because it is more heavyweight and often somewhat subjective. ToExpr, on the other hand, can usually be unambiguously derived with Generics.

Off top of my head, besides hashable, I can think of data-default-class and unliftio-core where this approach worked out very well. Also uuid-types, but that one is different, since it contains a type, rather than a type class.

Until there is large-enough buy-in from library maintainers, which I don't expect to see, this won't happen.

It's a chicken and the egg problem. Maintainers aren't gonna buy-in if they have to bring in tons of transitive dependencies. As you pointed out, even QuickCheck is too much of an extra dependency for some people.

I personally love seeing the beautiful color diff when tests are failing, so I would be a huge proponent of wider adoption of tree-diff in testing. I do believe this would be a helpful step in this direction.

I doubt vector or unordered-containers will depend on tree-diff.

If there was wider adoption of tree-diff in testing I'd be happy to make vector depend on a tree-diff-class (or maybe even a cooler named expr 🙂) if it had no other non-core dependencies. It is, of course, a long way away from that at the moment. We'd at least need a bunch of packages that integrated tree-diff with common testing frameworks like hspec, hunit, tasty, etc. I am planning on creating one for hspec for sure.

In any case, this was just an idea. If you think it isn't worth the effort. Feel free to close the issue. Maybe we can revisit this idea in a few years when people discover how cool tree-diff actually is. I barely found out about it two years ago and have been using it extensively ever since.