Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Stream<T>, IntStream, LongStream, DoubleStream?

You can't make this stuff up.

EDIT: what I'm trying to say is: why his remark is inflammatory and unnecessary, it's also wrong. This API is perhaps the single worse example of why java makes API's look worse than C#, and there is nothing to be done about it until the JVM stops erasing types.



Java's type erasure, while once considered a disadvantage, is now being recognized as one of the reasons other statically typed languages can be ported to the JVM. If Java reified types, it would make interoperability with other type systems extremely hard.


Yet somehow they made F# and scala run on the CLR. So: I'm calling bullshit.


F# team ask for modifications of the CLR (covariant delegates), porting a language on the CLR if you are not Microsoft is hard.

Scala never really run on the CLR, it's a vaporware, sorry a work in progress.


Yep, scala's .net back-end is discontinued, and one of the main challenges (I worked on it a bit) was indeed generating the proper generic signatures. (I hear people are using ikvm these days.)


For more context on why F# does in fact run into problems, see https://visualstudio.uservoice.com/forums/121579-visual-stud.... To my understanding, F# only allows type variables to vary, not type constructors (all generic variables must be escorted by a concrete type), and to go a step further, it doesn't allow type constructors to be used as higher-kinded type variables, which is useful sometimes. I see no reason why these couldn't be implemented on top of the JVM, though.


I've never understood why Java programmers dislike type erasure. In my mind, runtime type inspection is a bad idea for a supposedly statically typed language. It just seems like people are complaining that they can't do something they probably shouldn't be. If there's something you can't do without it then that means Java is poorly designed, not that type erasure is a bad idea.


To be fair, erased generics force autoboxing of primitives. Anyway, Java's combination of static and runtime types, though not pure by any measure, has actually proven quite useful.


I see this claim fairly often, but it seems like wishful thinking to me. There's nothing stopping a language targeting .NET from erasing its own generics to `List<object>`, `Map<object>`, `T<object>` if necessary, which would achieve almost exactly what you'd get with Java's erasure. And in the meantime, Java's approach requires any generic class containing arrays to box small value types, wasting large amounts of memory when those arrays are large.


> is now being recognized as one of the reasons other statically typed languages can be ported to the JVM

No, I really don't think so.


Type erasure has ups as well as downs. For one, it means you can write runtime polymorphic code when you don't care about static types - something that requires extra effort and a non-generic base type in .net. Any time you pass an object through a runtime polymorphic "hole" (e.g. a location of type java.lang.Object / System.Object), you lose the ability to pass along type parameters. In .net, if you don't have that abstract base class / interface, your only fallback is reflection. In Java, you've got List<?> or whatever it is.


Can you clarify your comment? I don't understand how those four types could be avoided with reified generics.


Because then you'd only have Stream<T>; IntStream would be just Stream<int>. The problem with reified generics is that they bake a particular type system into the runtime. While once a desired feature, I don't think the wide JVM community wants that any more.


To be fair, I don't think this is a problem with reified generics. The problem is that primitives cannot be erased to Objects in Java. Stream<int> only works in C# because int is an alias of Int32. Not because of reified generics.

The above should no longer be an issue when/if we remove the primitive types in Java 10(?) as we can safely use Stream<Integer> and Predicate<Integer> (or Stream<int>).


The runtime type erasure would have to be quite clever to realize that a ArrayList<Integer> should be backed by a primitive array of ints? One alternative is to erase ArrayList<T> into all variants (One for objects and one for each primitive type).

(In C# System.Int32 is a value type, and an "int" is equivalent). A List<Int32> is equivalent to a List<int> and is backed by an array of ints.)




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

Search: