We have https://github.com/alexknvl/newtypes, but we could also look at other options :)
Once https://github.com/scala/scala/pull/6074 is merged in and there is a scalameta release with https://github.com/scalameta/paradise/pull/207maybe~~ M10 already has it), that technique will be more usable. There are also some issues with IJ and newtypes with existential parameters at the moment. https://github.com/scala/scala/pull/6088 could improve the performance a bit (?). (
Maybe we should wait out this: http://docs.scala-lang.org/sips/opaque-types.html
Options that I see so far.
I am okay with either 3 or 4.
2 is still a question mark. but generally speaking, if cats.core has depend on something it has to be something that we have control over binary compat, otherwise Cats' bin compat promise becomes rather useless. so neither 1 or 2 should on the table.
I prefer 3. I'm not really okay with 4 myself. I think we're going to get stuck with a lot of things we don't want to be stuck with if we wait that long.
I prefer 4 since we are in the midst of this currently unfolding.
Also, can we have some concrete proposals of where we want newtype in cats? For things like EitherT or OptionT or something? Can we actually make a benchmark that shows some win first? Usually one more allocation in a stack 2-deep of monads is not actually going to be a big problem.
I don't want to complicate things, nor consider dropping 2.10, if we don't have a concrete win to look at.
I added this in gitter:
the newtype macro is very new.
it would be safe IF:
1) the encoding is binary compatible from release to release. Which it may or may not be.
and
2) it leaves no runtime calls in the generated code that make visible changes to the class files.
even if that is true today, it might not be true tomorrow. I think it is a risky bet, unless you are willing to stay on a fixed version after some change comes.
in my experience, binary compatibility with scala is a big pain.
For context, the use cases for newtype in in cats that I noticed recently.
KleisliSemigroupK and MonoidK as pointed out in #1932 OptionT, EitherT as suggested above by @oscar-stripe . Although I am not sure if they are the original incentive by @edmundnoble. To add to those, we also have NonEmptyVector and Nested come to mind. Also those defined in newts. :)
I think I can try for a stab at the use-cases we have in addition to the ones presented so far.
First and Last semigroup, as in x |+| y == x and x |+| y == yFirstOption, LastOption monoids, FirstEither, LastEither semigroups. Same for transformersSum and Product monoids for numeric typesValidated as a newtype over EitherNonEmptyList and NonEmptyVector@LukaJCB I am curious if you still plan to do the benchmark?
I haven't made a lot of progress yet. Tried for about an hour last weekend, but ran into some errors with JMH in combination with @alexknvl newtypes library, will have to do more research on that
Given the scope mentioned above, and the fact that the new type mechanism in Scala doesn't seem to be stable yet, also once the opaque type is out, we probably have to change it again. Now I incline to not include it in Cats 1.0 and lock it down. Users can choose their own new type lib for now. Cats internal usage of new type might be easier to manage (IRT to backward compat) if we keep the new type mechanism also internal.
I agree this is premature for cats 1.0.
I would like to reopen this discussion :)
Especially in light of 2.13 adding opaque types, I think we should consider our options again.
I don't remember who, but someone said somewhere that a macro internal to cats would be good because we could target pre-existing solutions (like those already done for NonEmptySet and NonEmptyMap) for older versions, while at the same time making use of the new functionality in 2.13.
I'll also try to get those benchmarks I promised a long time ago, to see what we can gain here :)
somewhere that a macro internal to cats would be good because we could target pre-existing solutions
It might be me, a macro based solution can probably support cross build. It could be internal to cats or since cross building new type would be very commonly used, cats can depend on https://github.com/estatico/scala-newtype and help support it.
I like the idea! I'm not super sure how stable that project is, but I've used it a lot and had only good experiences so far 馃憤
I did those benchmarks for a very simple parTraverse over Either, results seem very promising:
[info] Benchmark Mode Cnt Score Error Units
[info] ParallelBench.currentBench avgt 15 49.324 卤 0.299 ms/op
[info] ParallelBench.newtypeBench avgt 15 2.798 卤 0.028 ms/op
Full code here:
https://github.com/LukaJCB/newtype-bench
I can imagine results being even more dramatic when using nested Monad transformers.
This will be a good reason to go cats 3.0 (assuming 2.x maintains BC on Scala 2.12). Do we know the timeline of adding opaque type to 2.13?
IIRC, the timeline is Q3 for 2.13.0 and Q4 for 2.13.1 and I think Opaque types will be in the 2.13.1 version (it turned out to be harder to implement than originally thought)
On another note, do we think we'll release cats 2.0 and 3.0 at the same time?
@LukaJCB Just created https://github.com/typelevel/cats/issues/2296
@carymrobbins What do you think of the idea of having cats depend on scala-newtype? Do you think it will be stable enough, or a bad idea? Would love to hear your thoughts :)
@LukaJCB I like it! Do you think cats will look to use mostly the annotation macros (@newtype / @newsubtype)? I'm thinking before newtype gets a 1.0 release (which I think should happen before we have cats depend on it) we should consider removing the legacy encoding. If that works for you, then at this point the API should be considered pretty stable. A good plan of action may be to -
Let me know what you think. Also, feel free to adjust the above points if either I'm over/underthinking things.
I think we'll primarily use @newtype, I don't think we'd use @newsubtype anywhere really.
I really like that plan and hope we can get it started ASAP :)
If we go with the option 1 in this roadmap, this will be Cats 3.0 right?
Right, yeah it depends on how we handle our next release. :)
Most helpful comment
@LukaJCB I like it! Do you think cats will look to use mostly the annotation macros (
@newtype/@newsubtype)? I'm thinking before newtype gets a 1.0 release (which I think should happen before we have cats depend on it) we should consider removing the legacy encoding. If that works for you, then at this point the API should be considered pretty stable. A good plan of action may be to -Let me know what you think. Also, feel free to adjust the above points if either I'm over/underthinking things.