3 ms·
Unfortunately, this breaks the language semantics and I don't think it's a very good idea. Java is a static language. If these are a huge problem in your codeba
by exabrial 2y ago
Unfortunately, this breaks the language semantics and I don't think it's a very good idea. Java is a static language. If these are a huge problem in your codebase, you can discover the problems using nothing more than static analysis and healthy programming habits.
Personally I've never found nulls unintuitive or hard to use. Changing the core of the language to align itself with another fleeting in vogue trend is going to leave us with a bunch of garbage and tech debt when the trend inevitably falls out of style.
- tln 2y agoHow does it break the semantics? It "Compatibibly interoperates" according to the JSR! I don't think wanting not-null is going to be fleeting, but I'm sure with Java's long loooong 30 year history there have to be other "in vogue trends" that have left tech debt... Can you point to any?
- km144 2y agoIt doesn't seem like this is really focused on changing "the core of the language" though, is it? I guess I don't even really get that particular criticism for languages like Java and C# which I always kind of see as "big tent" languages. Both have been pretty engaged in adding optional features that allow support for different development paradigms in recent years. There's something to be said about the difference in philosophy here though. Some languages are much more focused on facilitating particular paradigms which is also completely reasonable. Java and C# are well-positioned in the industry to support many optional features and have that be a selling point. To your second point, I mean it's great that nulls are easy for you to use, I'm happy for you. But there are bad and good developers the world over that are contributing to bad practice with null handling when there aren't any guard rails. And not even necessarily because they don't understand null, but in some cases just because they don't think about it. Warnings are a reasonable solution to that IMO.
- crdrost 2y agoSo I think the biggest dig for me is that according to this JEP there are times that this code, String? y = null; if (x != null) { y = x.foo; } might trigger a null pointer exception. I don't mind the static error, if say `y` is not nullable but `x.foo` is nullable. But that's not at play in this code. Rather, these exceptions in the JEP come when `x.foo` is a `String!` but for various reasons either it hasn't been initialized yet and perhaps this code is occurring in a parallel thread, or due to various chicanery some null somehow was stored in it. (In the JEP the big case would appear to be that `x` is in this case a class with a static attribute `foo`? "Note, however, that this rule does not prevent some other class from trying to read the field during the class initialization process; in that case, a run time check detects the early read attempt and throws an exception.") To me, this is a minor change to "the core of the language" that betrays some bigger, more important change that has yet to be made to "the core of the language." Something like null tracking at the JVM level, or forbidding concurrent access to things that are being initialized... or maybe just that classes need new rules around what you can/can't do in their static initializations... some big semantic shift. Also, one of the more intricate parts of TypeScript has to do with types-as-unions, you want to be able to analyze code that says something like, if (x.foo == null) { return; } String! y = x.foo; and make the analysis step that this is legal and type-safe. But TypeScript can only do this because JS multi-threads on a message-passing model. Java doesn't do this, there is a race condition where `x.foo` was not null when the check was made, but then this thread slept for a millisecond while another thread with visibility of `x` modified `x.foo`. So in Java I think you need to correctly mark the above typecheck as "does not pass" while the closely related version, String? z = x.foo; if (z == null) { return; } String! y = z; would presumably need to pass static analysis because you can determine that `String? z` is not reachable from any other thread. So your static type-system now needs to have some heuristic "reachability system" that it appeals to, and it has to be a heuristic because you're not going to reimplement something as sophisticated as borrow-checking in Java.
- vbezhenar 2y agoThis code is not correct for TypeScript because it could be Proxy with getter. It works only because TypeScript types are not checked at runtime. Java approach is correct one. If you want to ensure that value is not changing under your feet, you need to save it to the local variable.
- marcosdumay 2y ago> might trigger a null pointer exception Every OOP language can behave badly at the data constructors. Every single one has some lightly-communicated rules that you must not break and are hard to verify.
- eklavya 2y agoHow do you know what is or isn't null?
- jayd16 2y agoYou can not like the proposal but claiming that we can be null safe with just static analysis? c'mon now.
- kelnos 2y agoEliminating null pointer dereferences (or NPEs, in this case) as a class of bugs is not a "fleeting in vogue trend". It's a useful and IMO necessary step to make programming less error-prone in general. > Personally I've never found nulls unintuitive or hard to use. That's not the argument. The argument is that it's easy to mess up their use without realizing it, leading to bugs that only show up intermittently at runtime. I'm just disappointed that this JEP doesn't go far enough; the compiler/runtime will automatically narrow types (e.g. auto-cast from String! to String), without warning, and possibly throw NPEs. That should be a compile-time error.