Hacker News new | past | comments | ask | show | jobs | submit login

Why would type erasure affect the front end language? I'm generally interested.



One of the earliest use cases for implicits is that in Java most types are erased but Arrays aren't, so you can't instantiate an Array in a generic method without having some way to pass the concrete type through.


I do not see why this problem cannot be solved by a compiler rather than a language feature. The type is statically known. It may require additional metadata alongside class files for separate compilation, but I don't see this as a big issue.


Scala needs to interoperate with other Java languages, and there is no platform-wide spec for supplying such metadata.

Even if there were, it couldn't be statically known at compile time in the case where a library written in Scala is being called by code that was written at a later date.

And even without that consideration, types still cannot be statically known in cases where you're being handed objects whose type is not determined until run time. Which happens all the @$#% time in Scala, due to its use of algebraic data types.

So, e.g., Java's run-time has no real way of expressing the type `Option<List<String>>`. You can declare it and get some compile-time checking, but that's all erased before the final bytecode is generated. There's no such thing as `Option<List<String>>.class`. This really limits what you can do with generic code. Scala added its own parallel type tag system to get around that. It's weird as heck and only really usable from other Scala code, though.


> Scala needs to interoperate with other Java languages

But does it? Can I even use e.g. a Scala collection from Java? (let alone Clojure, Kotlin, etc) Certainly it looks easy to import and use Java objects, but that looks to be the extent of it.

> it couldn't be statically known at compile time in the case where a library written in Scala is being called by code that was written at a later date

When you build some new code that uses an existing library, any parametric polymorphic type variables get instantiated at the use sites. Where I admit this isn't true, is the adhoc polymorphic dynamic dispatch via subtyping, but this wasn't given to me as an example. I don't see that ArrayLists and ADTs should present a problem.

> types still cannot be statically known in cases where you're being handed objects whose type is not determined until run time

Again, I think you are referring to dynamic dispatch here? I agree this could be a problem in open class hierarchies. But the ADT encoding in Scala is a closed statically-known hierarchy, so I can't see why it has to cause problems. Truly "generic" or parametric polymorphic code should not depend on type tags or even be allowed to introspect the runtime type, doing so violates parametricity, which ultimately reduces our ability to reason about the code.


> Can I even use e.g. a Scala collection from Java? (let alone Clojure, Kotlin, etc)

Yup to all. Sometimes the code comes out looking a bit ugly (e.g, you can access default parameters from Java, but it's done by calling methods with kind of awful auto-generated names), but the only things you really can't get at are things that relies on implicits, type tags, or traits with fields.


The type within a generic method can't be statically known. Consider a generic library method that creates an array somewhere deep in its internals, and is called from an application compiled separately.

Now of course you can say that library method requires some extra information from its caller - but how do you reflect that in the method signature in such a way that the binary compatibility constraints are clear and it remains intelligible what the signature is when invoking that method from Java?


If it creates a specialised concrete array at runtime, then it can't be a truly "generic" method (whereby I assume generic here means parametric polymorphism?). If you want to specialise object arrays to primitive arrays for efficiency, then I do not see why this cannot be a compiler optimization, since the types are statically known at the use sites.

Perhaps Java interoperability is the reason for the choices Scala made, but it doesn't appear that e.g. Scala collections can be used from Java?


> If it creates a specialised concrete array at runtime, then it can't be a truly "generic" method (whereby I assume generic here means parametric polymorphism?).

I'd argue it is, because the semantics of an array are the same whatever that array contains. In any case, there's no nice alternatives: a lot of Java APIs use Arrays, so not being able to work with them would be unpleasant, while having contexts in which you could work with existing arrays but not instantiate new ones would be weird and not a good fit for an immutability-oriented language like Scala (it would match what Java does, but Java is a lot more mutation-oriented).

> not see why this cannot be a compiler optimization, since the types are statically known at the use sites.

The use site for the generics could be arbitrarily many compilation units away from the code that instantiates the array. If it were just primitives then we could use @specialized and generate multiple copies, sure, the issue is that Java arrays are unboxed for any type including custom ones.

> Perhaps Java interoperability is the reason for the choices Scala made, but it doesn't appear that e.g. Scala collections can be used from Java?

They can be used, though in practice it's cumbersome enough that you probably wouldn't want to. The current collections API was created after Scala was relatively well-established and so had different priorities from early language design.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: