4 ms·
Pardon my ignorance but I don’t see how the Wikipedia link supports your statement. Can you please elaborate?
by eecc 8y ago
Pardon my ignorance but I don’t see how the Wikipedia link supports your statement. Can you please elaborate?
- noelwelsh 8y ago"parametrically polymorphic" == has a generic type. So a function foo[A](x: A) = ??? // Implementation hidden for now is parametrically polymorphic, where A is the generic type (or type variable). The principle of parametricity says that `foo` should act in the same way no matter what type of value it is called with. Type erasure ensures this, because it prevents `foo` from inspecting the (reified) type at runtime. If types are not erased then `foo` can behave differently when given, say, a `String` or an `Int`. Why is parametricity important? It makes code easier to reason about. Parametricity means no special cases to remember. It makes everything more uniform and simpler. In fact there is only one valid implementation of `foo` above, and this is the identity function. foo[A](x: A) = x Looking just at the type signature of `foo` tells you everything there is to know about it---which is quite remarkable! This reasoning principle is sometimes called "free theorems".
- amaranth 8y agoThis is an argument against specialization, not against reification. With type erasure your compiler can't perform type-specific optimizations, at least not without a JIT and borrowing some optimization techniques from dynamically typed languages.
- noelwelsh 8y agoI don't think we agree on definitions of terms here. For me type erasure means that the programmer cannot access a runtime representation of a type. A "runtime representation" is what I mean by "reified", as from the programming language theory perspective types only exist at compile time (and it is values that exist at runtime). Type erasure, as I use the term, is compatible with type specific optimisation. For example, the MLton compiler for Standard ML supports monomorphisation of polymorphic code, which in turn allows unboxing: http://mlton.org/Monomorphise http://mlton.org/Monomorphise The compiler is free to use whatever representation it likes, which includes a reified representation for use in, say, dynamic linking, so long as it doesn't break the language semantics (by exposing this to the programmer, for instance).
- amaranth 8y agoOf course, guess I shouldn't comment before the caffeine kicks in... I was thinking without reified types the JIT can't optimize it easily then got stuck on that. Of course the compiler could do so, Java just doesn't have an optimizing compiler.
- pron 8y agoI believe that the class file does retain the specific generic instance at the use-site, it's just that there isn't much type-specific optimization that's applicable to reference types beyond what HotSpot does anyway (which is stronger than what would be available by the generic instance type information). It's possible that Java AOT compilers could make use of this information.
- DougBTX 8y ago> If types are not erased then `foo` can behave differently when given, say, a `String` or an `Int` Perhaps worth pointing out that this doesn't apply to languages like Java and C# though (which I think is the most common comparison, since generic support is quite similar between the two, but Java has type erasure and C# doesn't) as both languages support `instanceof` and `getClass`, which would allow a function to change its behaviour based on the type of its arguments. It seems that once the type of an object can be determined at runtime, the argument that it is beneficial to hide the type of a generic parameter is quite a bit weaker. It also removes some useful features, eg, without type erasure, this is possible: collection.getFirstValueOfType<Foo>() including compile-time checks that the collection can contain elements of type Foo.
- noelwelsh 8y agoYeah, it's an interesting design decision in the context of Java. There are certainly lots of Java developers who think erasure is a mistake. I think things like `instanceof` are the mistake, and reifying generics is piling mistakes on top of mistakes, but then I've been hopelessly corrupted by FP. I freely admit this isn't a useful stance to take if one is focused on evolving Java as it currently exists! :-) My above post was mostly about explaining the concept of parametricity, though, and not so much about justifying it.
- DougBTX 8y agoYes, I have to agree about `instanceof` and friends being tricky. Often they seem to come up as a quick fix for some larger architectural problem, resulting in long-term debt. The idea of inferring the set of possible implementations of a function from its signature is neat.
- jdmichal 8y agoI view non-reified types as a mistake in Java, because it's easy to work-around: <T> void doStuff(Class<T> type) There, now you are guaranteed by the compiler to have the type of `T` at runtime. With this simple a work-around, it seems silly that they just didn't properly reify them and call it a day. That being said, it's also such an easy work-around that it's simply annoying at this point when I need to include the extra parameter(s) to get the type.
- eecc 8y agoI see, but what if I want to write a generic function where these types are somewhat constrained? (eg: ordered, numeric, is functor) what technique should I use then?
- tome 8y agoThe argument goes something like "Parametricity is a good thing and you can't have parametricity without erasure".