Open travisbrown opened 5 years ago
:+1: We recently just merged a PR to fix package objects in kernel https://github.com/typelevel/cats/pull/2785 I didn't know objects within package objects are pain for Java users. Under that light, I agree we should move them all to package objects. We might be about to make the change without breaking BC in the following way: Make current objects package private and deprecated. Create new replacements package objects. This passed the mima and compilation but I have tested it from user site yet. Better to test it in binCompatTest module. I can investigate more when I get back to computer later today. I also agree that all traits that aren't intended to be inherited externally should be made package private. That change should be BC. We should also add it to guidelines..
The best way I've seen to ensure good ergonomics in Java is by having Java tests (see akka/akka for examples of some duo-testing, maybe even some tidbits).
@dwijnand I'm not advocating putting a lot of effort into supporting usage from Java—this is more just avoiding gratuitously making life for Java users more difficult than it already is by doing stuff in Scala that isn't idiomatic anyway.
Even with the best intentions in mind, I've found the only way to safeguard is by actually writing the Java that uses the API. You get to (re)experience all those wonderful differences in syntax, in type inference, in user-site vs definition-site variance, in nesting, in access modifiers, etc... How much to invest in that, however, is up to the maintainers.
There's currently a lot of inconsistency in the way
cats.instance
andcats.kernel.instances
are implemented, which can be extremely frustrating, especially for people trying to work with Cats from Java), or for contributors who want to know where to add something (e.g. me, in the past), or for anyone thinking of pointing to Cats as an example of a thoughtfully-structured Scala library (e.g. me, now).For example, all
cats.instances.xyz
are defined as objects inside acats.instances
package object (which seems completely unnecessary and messy for Java users), except forcats.instances.symbol
, which for some reason is defined as a package object in its own file. The cats-kernel instance packages follow the same approach, with eachcats.kernel.instances.xyz
being a package object.Whether or not
BinCompat
and prioritizations traits are package private are also inconsistent across theinstances
packages.In my view Cats should follow the cats-kernel approach consistently across both kernel and core, and all compat and prioritization traits should be made as private as possible without breaking the build. I'm happy to do this myself if people agree it should happen, but since these changes will break binary compatibility I guess they have to wait for 3.0? It's a shame to have to tell users who need Java compatibility that they have to roll a bunch of their own awful boilerplate because some bad decisions that made it into 1.0 will necessarily live 2+ years or whatever.