refined
refined copied to clipboard
Experiment with newtypes and scala-newtype
RefineJavapSpec.scala shows the boxing behavior and runtime overhead of the different refinement carrier that refined supports which are currently Refined
, shapeless.tag.@@
, and scalaz.@@
(via the refined-scalaz module).
For reference types, all three carrier types do not box but using Refined
causes an additional function call. For value types only shapeless.@@
does not seem to box but causes two additional function calls. While the runtime overhead of shapeless.tag.@@
and scalaz.@@
is lower than for Refined
, the latter is less susceptible to compiler bugs and quirks like:
- #21 (aka https://github.com/scala/bug/issues/8740) (
shapeless.tag.@@
does not work with aliases) - https://github.com/circe/circe/issues/220, https://github.com/alexarchambault/argonaut-shapeless/issues/31, https://github.com/circe/circe/issues/784 (generic derivation with
shapeless.tag.@@
andscalaz.@@
does not work reliably)
We should experiment if @alexknvl's https://github.com/alexknvl/newtypes or @carymrobbins https://github.com/estatico/scala-newtype could provide a viable replacement for Refined
with lower (or zero) runtime overhead.
@fthomas FWIW, I recently added @newsubtype
macro support, which gets us unboxed primitives -
https://github.com/estatico/scala-newtype/pull/14
I plan on cutting a release including this feature in the near future. If folks are wanting this sooner rather than later I can prioritize as need be.
@carymrobbins Unboxed primitives sounds great and the subtyping relation fits well for refinement types. I'll will definitely try that for refined. There is no hurry to cut a release from my side, It'll take a me little while before I can do these experiments.