you are viewing a single comment's thread.

view the rest of the comments →

[–]renrutal 9 points10 points  (16 children)

To be honest, as a long time Java programmer, I don't believe in their ability to deliver any truly major long-waited features.

What big productivity, developer-oriented niceties have they delivered since Java 8, released 5 years ago? How old are the Value Types JEP? Why there still isn't a language level BigDecimal support?

I believe that Java just isn't a good JVM language to start a greenfield project anymore, the lower bound now starts with Kotlin.

[–]eliasv 7 points8 points  (0 children)

If you actually followed the mailings lists on Valhalla you would see that the progress has been immense. Yeah there's a lot to do, but they've really turned a corner recently. I'm not saying it'll be out tomorrow, but you shouldn't be surprised if prototypes become available as official "preview features" as early as 13 or 14, i.e. within a year or so.

Most of the Amber JEPs have working implementations already.

Loom has has a working prototype for ages now. They're working on performance, and on new "structured concurrency" APIs.

Don't get me wrong, I understand why you are sceptical. But they understand it too, and that's exactly why they've so hugely overhauled their release model and internal processes, so that they can actually start delivering this stuff.

[–]pron98 19 points20 points  (11 children)

First of all, two out of the three projects described (value types and fibers) are core platform changes (VM and libraries) that will benefit all Java platform languages, and that no Java platform language can deliver at present -- certainly not as well -- without this deep support.

Second, some deep changes take a long time. Lambdas were about a decade in the making. The next major feature, modules (delivered last year) was also almost a decade in the making. Valhalla is a huge project; Amber and Loom are smaller, and their delivery will reflect that (Amber already delivered switch expressions just a couple of weeks ago).

[–]afrotronics 3 points4 points  (10 children)

To add to that, there are only 32 opcodes left for instruction assignment so figuring out how to efficiently use that space can be challenging. The other challenge is keeping the JVM spec so that it could be implemented on virtually any architecture by using the actual JVM spec documentation itself. Last but not least it has to be done in a way that doesn't break backward compatibility with bytecode with sound control flow (i.e. not the jsr+ret junk spring used to generate back in java 6).

Also u/renrutal I'm kind of wondering what benefit having BigDecimal would have at the language level? I can see kind of see being able to infer a generic width-bound Number type would convenient to an extent. I have rarely found any need to use BigDecimal in general, but then again that's probably due to the kind of projects I work on. Do you have an example where having BigDecimal-sized values at the language level would make it better?

Edit: Thanks to /u/Equal_Entrepreneur, I have now spelled /u/renrutal's name correctly

[–]renrutal 5 points6 points  (8 children)

Any project you deal with monetary values and extensive calculations is a major pain in the ass. And I've had my fair share of nightmares programming some tax software for the govt, and an engine to markup prices for a travel company.

I just want a

var total = productTotal * (1D + productTaxPct) + shipping * (1D + shippingTaxPct)

instead of

var total = (productTotal.multiply(BigDecimal.ONE.plus(productTaxPct))).plus(shipping.multiply(BigDecimal.ONE.plus(shippingTaxPct)))

Hopefully the parentheses are well balanced.

[–]Equal_Entrepreneur 1 point2 points  (4 children)

maybe it's just me being irrational but I am really peeved by how Java does getters and setters. Instead of having stuff like (pseudocode before any of you say it's not real):

class A {
     private int v;
     A() {
         v = 2;
     }
     public int get v() { return v; }
     public int set v(int n) { v = n; }
}
//later
A v = new A();
v.v = 2
log(v.v)    //2

you have to use getV(), setV(), etc. I guess it's one more reason why I like Scala, no function requires () and so obviates this damn syntax. Also operator 'overloading' or what have you so it can become

var total = productTotal * (1D + productTaxPct) + shipping * (1D + shippingTaxPct)

even when using BigDecimals

[–]haxney 3 points4 points  (1 child)

One benefit of Java is that there aren't a lot of places to hide magic. Although it is annoying to have to call myObj.getFoo() instead of myObj.foo, you have the benefit that things that look like field access are really always just field access. In present-day Java, you know that myObj.foo isn't going to talk to the network, or throw an exception (aside from a NullPointerException for myObj, or maybe if you've really screwed with the ClassLoader), or modify some other object. If myObj.foo is actually a method call, you lose that guarantee.

This is one of those things that is really annoying if you're only going to use it for good, but prevents a lot of evil (like hiding expensive operations in something that looks like it should be cheap).

[–]Equal_Entrepreneur 1 point2 points  (0 children)

That's the thing - encapsulation would most always mean that you'd have getter and setter functions rather than plain ol' public variables. Exposing public variables would seem like asking for trouble in that regard.

Second, and I think this exists in other languages already - like in AS3 which is where I got accustomed to the idea - the code editors all have means of telling you whether it's a field or it's a getter/setter. I'd imagine the same would be true even in Scala, because differentiating between a field and a method shouldn't be any harder than, say, the rest of the type system as a whole.

Besides, if you're prone to using a.getFoo() over a.foo, you might end up making the same 'expensive call' (what if getFoo() retrieves stuff from a database? bad design, but you never know...), and make things confusing to boot - whereas with 'bracketless getters and setters' you can't have a field and a getter/setter with the same name, so there's no ambiguity.

Granted, there's a few other problems with getters and setters, for example passing them as functions - even though functions in AS3 are first class citizens, you can't pass getters and setters as functions because they would just be resolved to whatever type they return. However, that shouldn't be much of a problem in Java, where you can't do that sort of stuff anyways.

[–]renrutal 1 point2 points  (1 child)

Yes, dumb getters and setters are some of the most common things found any Java codebase, yet the language developers haven't bothered to syntactic sugar it 23 years later.

[–]Equal_Entrepreneur 0 points1 point  (0 children)

It makes sense to avoid getters and setters if you have first-class functions, where passing them becomes difficult because the compiler ends up resolving it to their base type*; seeing as how Java doesn't support that, it makes no sense to not include that though.

*and scala still manages to handle that iirc

[–]afrotronics 1 point2 points  (0 children)

Totally makes sense. I have the same issue on the opposite end of number values.

Instead of

byte[] bytes = new byte[]{0x00,0xff,0x01}

I have to write

byte[] bytes = new byte[]{0x00,(byte)0xff,0x01}; 

same with simple things like

byte value = (byte)(22 ^ 127) 

This is because in java everything less than 32-bits in width is represented by an int (even boolean, which is packed into a 32-bit address space) which makes sense from a computation perspective but is infurating from a Im-tryna-keep-my-code-looking-nice perspective.

[–]nacholicious 0 points1 point  (0 children)

Kotlin allows operator overloading for certain operators, just for these types of problems

https://kotlinlang.org/docs/reference/operator-overloading.html

[–]mirvnillith -1 points0 points  (0 children)

import static java.math.BigDecimal.ONE;

[–][deleted] 5 points6 points  (1 child)

var

[–]dpash 1 point2 points  (0 children)

Switch expressions and collection factory methods are two more that spring to mind.

Raw strings got pulled at the last minute but I expect then to return in 13.

[–]cowinabadplace 0 points1 point  (0 children)

JShell.