4 ms·
Honestly, none of those differences you listed seems especially compelling to me, except possibly for the ?. operator. What would be compelling: Array types th
by akoboldfrying 2y ago
Honestly, none of those differences you listed seems especially compelling to me, except possibly for the ?. operator.
What would be compelling: Array types that don't hate generics, or generic collection types that don't hate primitive types. Does Kotlin improve on Java at all here? It's such a pain having to remember this bonus complexity when all I want is a consistent way to manage a bunch of things. (I suspect not, as I think the limitations are at the JVM level, but I don't know.)
- t-writescode 2y agoOut of curiosity, what are you wanting that autoboxing doesn't resolve?
- kjeetgill 2y agoStripping out Maps/Lists with boxed keys and values is the first easy thing to do when perf tuning a piece of code. It's so frequently impactful that it's worth doing immediately without any measurement. You just swap them out with fastutils or trove and call it a day.
- akoboldfrying 2y agoI think you're right, that's probably the best (lowest mental overhead, fewest footguns) way -- always use a List instead of a raw array, and always box primitive types. This also avoids the parallel explosion of Stream types and methods (IntStream, mapToInt(), etc. (and the fact that there's no BooleanStream or ByteStream, etc.)). That said, I tend to get bitten by the fact that == on 2 boxed numeric values is roughly as misleading as possible -- it does reference comparison, but interns small integer values only, so (Integer)42 == (Integer)42, but (Integer)420 != (Integer)420. (So the small values you probably used in your unit tests will appear to work just fine with your broken, ==-using code.) ETA: Deleted a misplaced "new". I also don't love that, e.g., ++x does a heap allocation + deallocation if x is boxed (since boxed types are immutable). But usually I care more about the cycles I spend coming up with correct code than cycles the CPU spends executing it.
- sjrd 2y agoScala solves the primitives-in-generics, and it significantly improves on the array-hates-generics. So it's possible.
- haspok 2y ago10+ years in the making, at this year's Devoxx Brian Goetz said that they are almost ready with the design of Project Valhalla and can start JEP-ing it in future JDK releases. No timeline yet, so we probably will not see it until the next-after-next LTS release (29?)... But Java, like Cobol, is not going anywhere, so the wait will be worth it.
- akoboldfrying 2y agoGreat, though is that perhaps orthogonal to my complaints? My vague understanding is that Valhalla is about transparently allocating local objects on the stack instead of the heap when possible (i.e., when escape analysis confirms that they can't "get out" of the method that declared them), the way primitives are now.
- haspok 2y agoBut these are the same problems! I'm not intimately familiar with the current state and internals of project Valhalla, but they were proposing `primitive classes` backed by primitive types, allowing said class to be used as a type in generic code. Moreover, primitives would become ValueObjects, so you would have your int[] which would also be an Object[]. In other words, the difference between primitives and objects would be much smaller in terms of the language. Bottom line is, you could have your cake and eat it too - have an int[] that looks like a List<Int>, and vice versa, while retaining the performance characteristics of an array.
- akoboldfrying 2y agoThanks, I'd thought that the goal was to reimplement aspects of the compiler+JVM to preserve existing language semantics but be more performant, but from what you've written I take it that the goal is actually to expand the language semantics themselves, in a way that would bring primitive types and objects (and thus generics) closer together.
- yarg 2y agoValhalla is what you want, at least for some of it. https://openjdk.org/jeps/402 https://openjdk.org/jeps/402 interface Box<T> { T get(); void set(T val); } interface IntBox extends Box<int> { int get(); void set(int val); } https://openjdk.org/projects/valhalla/ https://openjdk.org/projects/valhalla/
- bberrry 2y agoKotlin does improve on the primitives/boxed situation. For example in Kotlin there is just "Int", not both "int" and "Integer". The language will use stack-allocated primitives wherever possible and boxed objects when necessary (in Collection generics or when you've explicitly opted into nullability). The distinction is abstracted away from you as a programmer. Sounds like the consistency you want.
- akoboldfrying 2y agoWonderful, thanks!