Its author moved on before it was ready to be integrated and maintained by other people, and no one picked it up.
In Scala 2, the following code will not box any of the integers, AFAIK (someone correct me if I’m wrong):
List((0, 1), (2, 3), (4, 5)).foreach(x => useAnInt(x._1 + x._2))
In the current implementation of Scala 3, the tuples will box the integers they hold, and the function passed to foreach
will have to unbox them before adding them up.
You’re not wrong. If you javap -c
it you’ll see that Scala 2 uses Tuple2$mcII$sp
(specialized) throughout, rather than an ordinary Tuple2
, to avoid boxing the Int
s. Whereas Scala 3 boxes them.
Is the art of writing one’s application as a set of libraries totally lost?
^ was a jokey comment to address a serious issue: Adding a burden for library writers is actually harming the ecosystem enormously… it requires a lot more time and resources for library writers/publishers to keep up. Cross compilation/special rules, etc. only adds to that.
Now that inline def works on opaque types. Do we need those specialised classes for primitives types anymore, @gvolpe? This should be enough I think?
trait NewType[Wrapped]:
opaque type Type = Wrapped
inline def apply(w: Wrapped): Type = w
extension (t: Type) inline def value: Wrapped = t
given (using CanEqual[Wrapped, Wrapped]): CanEqual[Type, Type] = CanEqual.derived
Two and a half years after this thread went quiet, and from my POV opaque type
remains significantly less easy to use than Haskell’s newtype
.
Haskell gives you a nicely-made box to put your data in, while Scala gives you a flatpack and a screwdriver and insists that’s just as good
Re-reading this thread I think @gvolpe provided an accurate description of where Scala’s limitations are, but his proposals seemed to fly into a wall of opposition.
One thing I’d add to the ask is the ability to auto-derive arbitrary type-class instances by delegation to the underlying type, as in GeneralizedNewtypeDeriving
:
newtype Dollars = Dollars { getDollars :: Int } deriving (Eq,Show,Num)
How many lines of code does it take to express the above in Scala atm?
I think it should be possible to implement deriving on an opaque type, the issue is that because opaque types are so flexible, what would the deriving
clause desugar to? One idea I had was that it still desugars to e.g. Show.derived
in the companion, but then we provide the user factory methods to select which kind of mirror they should provide for an opaque type.