17 ms·
Null-Restricted and Nullable Types
- rvcdbn 2y agoIMO there really needs to be a way to mark all variables non-null by default at package or at least a file level. Otherwise there will be a strong safety argument for always using T! syntax on almost every variable and this will just be a lot of noise.
- foolfoolz 2y agoi don’t think it will be that bad. we have a standard in our projects today that all java variables in code we own are not null. if you would like to have a nullable variable, you must annotate it with @Null this is only an issue at the boundaries of our code where we interact with libraries. i imagine that will be the case with this new syntax as well
- jayd16 2y agoIf I understand you, then you're not getting any compiler check support for misuses, correct?
- lolinder 2y agoI have to assume they have a lint rule for that. With good tooling compiler error vs lint error is a distinction that matters about as much in practice as parse error vs type error—your editor and CI pipelines will yell at you either way.
- jayd16 2y agoI suppose an aggressive linter could assume unmarked should be treated as non-null and at least demand nullability markup where needed.
- rileymichael 2y agoUnder "other possible future enhancements": > Providing a mechanism in the language to assert that all types in a certain context are implicitly null-restricted, without requiring the programmer to use explicit ! symbols.
- sswezey 2y agoThe formatted JEP link: https://openjdk.org/jeps/8316779 https://openjdk.org/jeps/8316779
- lbalazscs 2y agoYour link is only for value types, but this one is more general, it's for any type. Obviously the two are related, but not the same. Nullability for value types has performance implications as well.
- MBCook 2y agoAs a Java developer this is great. I’ve started to use the @Nullable and @NotNull annotations a lot for parameters and return values and they’re very helpful. But they never made it into the language, so it’s only ‘enforced’ by the IDE and it’s a lot more visual noise than ? or ! which I’m already used to from other languages. I can’t wait, I hope it gets in.
- exabrial 2y agoUnfortunately, 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.
- rendaw 2y agoIt's interesting to see this right on the tail of https://jspecify.dev/blog/release-1.0.0/ https://jspecify.dev/blog/release-1.0.0/ by Meta et al. That was done AFAIK because JEP-305 died and it didn't seem like Oracle was going to ever do anything about it. Did Oracle do nothing to coordinate here?
- tadfisher 2y agoI think you mean JSR-305 [1]. Even though the initiative died in committee, you can still use the reference implementation [2] and hundreds of thousands of projects do so. Most static analysis tools and IDEs support it as well. JSpecify takes advantage of Java 8 features (e.g. annotations on generic type parameters), so it's strictly better, and I believe at least the IntelliJ IDEs support it. [1]: https://jcp.org/en/jsr/detail?id=305 https://jcp.org/en/jsr/detail?id=305 [2]: https://central.sonatype.com/artifact/com.google.code.findbugs/jsr305 https://central.sonatype.com/artifact/com.google.code.findbu...
- declan_roberts 2y ago> In a Java program, a variable of type String may hold either a reference to a String object or the special value null. In some cases, the author intends that the variable will always hold a reference to a String object; in other cases, the author expects null as a meaningful value. Unfortunately, there is no way to formally express in the language which of these alternatives is intended, leading to confusion and bugs. Casually just describes one of the largest sources of bugs in the history of programming.
- Sohcahtoa82 2y agoCan someone explain to me how nulls are even a problem? I know the basics of Java and did some basic projects in it for my CS degree, but never used it professionally or in a large project. It seems to me that something somehow being assigned a null is a bug, but one that would stick out like a sore thumb. At some point, you're returning a Null, right? Any code calling a function that can return a Null should know that being handed a Null is a possibility and handle it, right? I'd think that eliminating Nulls is a bandaid over the wrong problem. Or is eliminating Nulls really meant to catch any potential NPE's at compile time as a way for force better error checking?
- HellzStormer 2y ago> Any code calling a function that can return a Null should know that being handed a Null is a possibility and handle it, right? Well right now, the only way to know is to read comments/docs. The problem is that for many older languages, the signature cannot make it clear that null is a possibility (unless you count "anywhere can be null regardless of the function", which isn't helpful). The goal is to have a real distinction between can be null and wont be null so that things can be made explicit and the compiler can actually highlight places where the handling is missing. It's a tool to help do exactly what you describe in a less error-prone way.
- recursivecaveat 2y agoThe thing is you don't know whether the method you're calling can return null. It's invisible to the type system. You can try to track the null-validity of every value with documentation, but this is tedious, error-prone, and the exact same problem types exist to solve accurately at compile time. If you try to add defensive null handling everywhere it makes for absurdly verbose code, and it's pretty dubious since you don't really know what the semantic meaning of the phantom nulls you're pre-emptively defending against are. Everyone everywhere always being more careful is the bandaid solution, if you lift the extra non-optional sum type into the type system you solve the problem permanently.
- hn_throwaway_99 2y ago> I'd think that eliminating Nulls is a bandaid over the wrong problem. That's not what is happening here. The issue with the current iteration of Java is that all type declarations implicitly include `null`. So you can do for example: // some method public String getSomeValue(); // client code String someVal = obj.getSomeValue(); At that point, the caller of the getSomeValue() can't depend on someVal being non-null. You say "Any code calling a function that can return a Null should know that being handed a Null is a possibility and handle it, right?" and that's really the problem. ANY method that returns an object type can return null, so, in theory, it would force all callers to do stuff like `if (someVal != null) ...`, which is really annoying if it has to be all over the place. This proposal makes it clear to callers whether a method can return null, or if it is guaranteed by the type system not to return null. That way, it is now possible for a method to state "I guarantee that I will only return a String, never null", and previously that was not possible (directly in the language at least - there were some kludgey workarounds like the Optional generic type). So this means that clients don't need to do tons of unnecessary null checks. This is definitely not an issue specific to Java. For example, TypeScript is clear that its types do NOT automatically include null, and it makes coding SO much clearer. For a type to include null (or undefined, but that's a whole other JS-specific ball of wax...) you must explicitly write e.g.: const foo: string | null;
- elric 2y agoArchive link because the site is currently down: https://web.archive.org/web/20240802081039/https://bugs.openjdk.org/browse/JDK-8303099 https://web.archive.org/web/20240802081039/https://bugs.open...
- promiseofbeans 2y agothe good old hn hug of death
- xxs 2y agoAhh they did switch to all loved "jira" - no surprises there.
- sebstefan 2y ago>It is not a goal (at this time) to apply the language enhancements to the standard libraries Speaking from experience being forced to use php, it's a hassle to have ahead-of-time guarantees on your data that you need to strip out or build back up everytime you interact with the (massive) standard library They should be a bit more enthused to add that kind of expressiveness to their STL and make it a first class citizen in the STL
- imtringued 2y agoHonestly one of the biggest problems with Java is that they are incrementally improving it, but then the new minimally improved code becomes legacy code for the next incremental feature. Legacy code that uses Optional is a liability for any proposal that uses explicit nullability and non nullability. Record types could have been non nullable by default and so on...
- slaymaker1907 2y agoI think you're reading "at this time" as "never" when in reality, they want to do that separately since that sort of conversion is a huge undertaking in its own right. Additionally, separating it into two steps allows them to more easily launch this as a preview feature, get feedback, and then commit to a design before trying to overhaul the whole standard library. If they try and do it all at once, that gives them little room to actually iterate on the feature.
- hnthr_w_y 2y agoforced? modern php is a bliss.
- sebstefan 2y agoIt's hard defending php in 2024 when you've used the alternatives that exist... It took two major versions to add types to both function arguments and return values and there's still no type-restricted data structures. Think "array of foo". Just overall, other than with bash, I've never shot myself in the foot more often than with php I despise that thing with a passion
- noelwelsh 2y agoI think we're still in the bashing rocks together stage of programming, but things like this definitely make me smile. Java is not an innovative language and the fact it is evolving towards something better shows that the industry as a whole is moving forward. We can't be more than a decade away from everyone being able to program in a language with the features of ML circa 1983.
- pas 2y agoScala is doing fine. ;P There's a huge inertia to "strictly wrong, but already existing", so there is a bias to keep maintaining those things. (And there are - at least - hundreds of thousands of programmers with huge status quo biases. We saw this mostly as C started to lose a lot of ground, finally, to safer languages with infinitely better tooling. It's that too many people put up with bad bad tools, mostly because they prefer very very incremental changes, and mostly those that give them results in "functional requirements".)
- staticlink 2y agoScala is doing fine-ish.
- xxs 2y ago>Java is not an innovative language Most of the innovation when it comes to concurrency, garbage collection, JIT did come from Java. Syntax - that's more of an opinion/preference. My gripe with yet another "improvement" of the language is still the lack of headerless objects (aka value classes) - JEP 401[0] [0]: https://bugs.openjdk.org/browse/JDK-8251554 https://bugs.openjdk.org/browse/JDK-8251554
- bkail 2y agonullability is directly related to the value classes effort (the top article mentions value classes, and the JEP you linked mentions nullability): in order to get the most benefit out of value classes, you need some way to express guaranteed non-nullability to avoid needing to encode null (imagine Point[] vs Point![]): https://cr.openjdk.org/~jrose/values/flattened-values.html#implementing-null-channels https://cr.openjdk.org/~jrose/values/flattened-values.html#i...
- jeroenhd 2y agoThe difference between this approach and the approach C# took when they implemented this a few years ago is intereting. With C#, you enable nullability in a project, and every variable is declared as non-null unless you explicitly mark it as nullable (or use compiler directives to disable nullability for a block of code). With this proposal, all existing variables will be effectively nullable, explicitly nullable, or explicitly non-nullable. Kotlin, another JVM language like Java, also follows the C# approach, assuming everything is non-null unless explicitly marked as being non-null, except Kotlin doesn't have backwards compatibility to worry about. Kotlin also offers a special `lateinit var` declaration for leaving a non-nullable type unassigned until initialization in another method, throwing a special exception on uninitialized access, which is an interesting workaround for some code patterns that this approach doesn't seem to cover. I wonder why the choice to offer three options was made. Why not keep the non-annotated variables as nullable and make annotated variables explicitly non-null instead? I can't think of a reason why you would want to declare something as nullable when not declaring anything automatically makes the type nullable anyway. I think I like C#'s approach better, although this has the benefit of being usable in a legacy code base without having to solve any of the nullability issues. Then again, the C# approach does immediately highlight nullability issues in a code base, whereas this proposal hides them the same way they've always been hidden. Additionally, I find this strange: > One method may override another even if the nullness of their parameters and returns do not match. This feels like a footgun for when a developer overrides/implements some kind of callback and returns null where the overridden method specifies non-null return values.
- foolfoolz 2y agohow does the project level null flag work for libraries? lets say a library was written with no nullability flag selected (legacy jar). i import that jar into my code. in my code i enable all variables as non-null by default
- gwbas1c 2y ago> This feels like a footgun for when a developer overrides/implements some kind of callback and returns null where the overridden method specifies non-null return values. I've caught "null!" in C# code reviews a few times: My response is usually "You can't fix your code by yelling at it." The reality is that C#'s approach also has some nasty footguns that require understanding the nuances of the "required" keyword, and when values are assigned.
- elric 2y agoCan't say I'm a fan of the proposed syntax. Random question marks and exclamation marks do not improve the readability of the language. Introducing new symbols wouldn't bother me as much if they made sense. E.g. square brackets make sense for arrays because they denote an area. Equal signs make sense for assignment and equality because of mathy history. But question marks and exclamation marks don't make much sense for nullability. Which is easier to understand? I don't mind a few extra keystrokes if it improves readability. private String? foo; private String! bar; // or private nullable String foo; private nonnull String bar;
- oftenwrong 2y agoWhich of these is easier to search for in a book or web page? Which will allow for clearer oral discussion? I prefer using long options in shell scripts for similar reasons. Easier for future maintainers to search for.
- dtech 2y agoT? is widespread syntax already. E.g. Typescript, C# and Kotlin use it.
- agumonkey 2y agoI'm still more in favor of Option<T>
- martinsnow 2y agoEw.
- dtech 2y agoWould be cool if Java got this feature, explicit optionality at a language level a la T? is an enormous developer QoL in Kotlin and Typescript in my experience. In Java there's tools like NullAway [1] but they're a hassle. Language-level support is leagues better than Optional/Maybe in my experience too because it keeps the code focused on the actual logic instead of putting everything in a map/flatMap railway. [1] https://github.com/uber/NullAway https://github.com/uber/NullAway
- j16sdiz 2y agoBreaking 30+ years of source compatibility? Why? Why don't just use any JVM languages?
- twic 2y agoThis change would not break any source compatibility.
- voidfunc 2y agoSome us actually work on real software with dozens or hundreds of other devs and not toys. We can't always just "use any JVM language".
- imtringued 2y agoI wish Oracle would just offer Java editions, where they break syntactical backwards compatiblity, but retain backwards compatibility on the bytecode level. Of course, 99% of the language should stay the same with most of the syntactical changes just getting rid of the annotation mess that proper Java would be.
- pjmlp 2y agoThat is already what guest languages offer, but then there is always the caveat that their subculture only sees the JVM as a bootstrapping tool for their little ecosystem.
- edem 2y ago[flagged]
- pjmlp 2y agoKotlin is only relevant on Android. And before someone tells me how they enjoy Kotlin on the backend, see StackOverflow 2024 results.
- Tainnor 2y ago> Kotlin is only relevant on Android Sure, that's why Spring has first class support for Kotlin, but go on. > see StackOverflow 2024 results. The number of people that enjoy Kotlin has absolutely no influence on my ability to enjoy or not enjoy it.
- pjmlp 2y agoSpring has first class support for any JVM language that helps them bring money to the table. Groovy and Scala were there first, where are all those Spring apps now? Heck I remeber when Groovy Spring was supposed to take over the Java Web application development, and alongside Grails wipeout all those Rails projects, with regular sessions at local JUGs. It definitly has an influence on available jobs.
- Tainnor 2y ago> Spring has first class support for any JVM language that helps them bring money to the table. The Kotlin support is on a complete different level. Go to https://start.spring.io/ https://start.spring.io/, you get an option of Java, Kotlin or Groovy - no Scala, Clojure etc. Dedicated Scala support especially never really took off. > It definitly has an influence on available jobs. I worked at two different companies on almost exclusively Kotlin codebases and have interviewed for several more. There are enough jobs to keep me employed with a good salary and even if those jobs disappeared, I would just learn some other language, no big deal. In the meantime, I get to use a language that's actually decently fun to write. I get that the very existence of Kotlin somehow offends you, but you don't have to shout it from every rooftop. There's enough space on the planet for everyone.
- dzonga 2y agoseems all the good things about Kotlin are coming to Java now. I will still prefer to work in Kotlin though as I don't have to deal with things like lombok though Java records are nice.
- esafak 2y agoBut Java programmers will still use the old idioms, and be stuck with their old code bases. It will take a long time before these things are in the wild, so Kotlin programmers need not worry.
- elric 2y agoJava has a long history of getting inspiration from other languages. Happy to see it's continuing to evolve at a decent pace, while mostly maintaining compatibility with previous versions.
- mmaniac 2y ago> In this JEP, nullness markers are explicit: to express a null-restricted or nullable type, the ! or ? symbol must appear in source. In the future, it may be useful, for example, for a programmer to somehow express that every type in a class or compilation unit is to be interpreted as null-restricted, unless a ? symbol is present. The details of any such a feature will be explored separately. I think this question needs to be answered now. The addition of ? is useless and confusing unless this is planned to eventually happen. I am inclined not to introduce breaking changes and to only have !.
- MBCook 2y agoIt’s not. The fact that it’s got a ? means a developer explicitly marked it and told you it’s nullable. The lack of a mark means you have to consider it nullable but no one has told you that setting it to null is the right thing. Things may still go wrong if you set it null though. It’s just the contract isn’t explicit in the code.
- jeltz 2y agoNot it is not. They mean different things. String? a = null; String b = null; String? c = ""; String d = ""; String! aa = a; // Compilation error String! bb = b; // Runtime error String! cc = c; // Compilation error String! dd = d; // Works!
- mmaniac 2y agoThanks for clarifying the distinction - that's worse than I thought. When an expression as simple as bb = b can throw something has definitely gone wrong.
- kaba0 2y agoIt has nothing to do with the expression’s simplicity. There are rules uphold by the compiler, and those are displayed in the easiest example possible. There may be additional rules that could show a warning in these cases (e.g. java can track whether a variable gets initialized in both branches and similar quite well), but that’s besides the point. Take these examples in a way that the only thing you know about variable `a` is its type.
- deleted 2y ago[deleted]
- ajnin 2y agoLooks good, finally a language-supported way to remove thousands of unnecessary Exceptions and null-checks. But the nullness-narrowing automatic conversions feel wrong. From the proposal : String? id(String! arg) { return arg; } String s = null; Object! o1 = s; // NPE Object o2 = id(s); // NPE Object o3 = (String!) s; // NPE Surely at least the two first cases should yield a compiler error. The last case you're explicit so it's borderline but I'd rather see something like : String s = ... if (s != null) { # Here the compiler knows that the effective type is String! String! ss = s; # OK } Like this no possibility of error.
- slaymaker1907 2y agoAs someone who has written Java in industry, I'd rather dynamic checks only happen when I explicitly ask for it and have everything else done statically. Bean validation works great since while the object might be incorrect temporarily, I know it's valid as soon as I validate it explicitly (or it gets validated by the framework before entering my code). In fact, I'd even prefer Objects.requireNonNull(s) be used instead since that's even more explicit than the cast in the last case. However, I'd also like for there to be an Objects.unsafeForceNonNull(s) that just bypasses any explicit check unless there's some sort of optimization that would otherwise prevent. The unsafe method lets you implement your own requireNonNull without adding a bunch of complicated static analysis.
- ta234234234 2y agoIs it really though? If your problem is introducing null's into the API, I'm not sure that's a language error. I mean I get it, its verbose and cleans things up. But isn't the problem the coders doing it?
- The_Colonel 2y agoCoders work with what they have. The work itself is shaped by the tools the workers use to produce it. If you give workers inadequate tools, you can't expect high quality. Java currently doesn't provide any decent (general) solution for the problem of nullability - JSR-305 is a failed spec, Optional is very verbose, doesn't work for many use cases (e.g. isn't Serializable) and funnily enough there's no guarantee the Optional instance is non-null, value types (primitive and the preview support for complex ones) obviously covers only very specific use cases.
- Sankozi 2y ago"It is not a goal to require programs to explicitly account for all null values that might occur; unaccounted-for null values may cause compile-time warnings, but not compile-time errors" This is a bad decision. Java is mostly statically typed language, why introduce another dynamic behaviour? Hope there will be easy way to promote such warnings to errors.
- yxhuvud 2y agoThey can't do that or it will break all java programs in existence. Enforcing that would force all programs to be rewritten to handle null responses everywhere. With this addition they can apply the forced null handling to only operations involving the new types, and thus not break anything. And yes, languages where the type systems force handling null/nil in all cases is a lot nicer. But that is not what the current Java is. This will still be a big improvement.
- Sankozi 2y agoIt will only break existing programs if they start introducing Type! into existing APIs. I understand that introducing ! types in existing Java libraries would be nice, but I much prefer the ! mechanism to be more "correct". I agree that it will be a big improvement either way. It seems we need some annotation akin to @Deprecated(forRemoval = true). Something like @NotNull(willBeEnforced = true) that would only emit a warning but informs the user that soon there will be a breaking change related to nullability.
- cesarb 2y agoOne annoying detail of this proposal, is that it swaps the meaning of the nullness markers compared to Kotlin, which uses ! to mean "it came from Java and had no nullability annotations so we don't know" and no marker to mean not nullable (https://kotlinlang.org/docs/java-interop.html#notation-for-platform-types https://kotlinlang.org/docs/java-interop.html#notation-for-p...).
- vbezhenar 2y agoThere's no "!" syntax in Kotlin for developers.
- jpgvm 2y agoCorrect. Platform types are non-denotable.
- mike_hearn 2y agoNot a big deal. The exclamation mark only appears in IDE tooltips and things, you can't express it directly. It could therefore be changed without breaking anything. If you want a 'flex type' you have to use type inference: // Java Baz bar() { return new Baz(); } // Kotlin val foo = someJavaObject.bar() foo now has type Baz! but the moment you declare the type of foo explicitly you're forced to pick, and an NPE check is done at that moment.
- drinkcocacola 2y agoIt is indeed annoying. For Kotlin, its advantage is that it had the nullability concept from its inception. For Java, they need to make sure previous code behaviour does not change, meaning that they need to add an additional marker to the explicitly mark "not null" types. Probably in some years from now once codebases exclusively use this feature, there would be a way to tell the compiler that the default type (without marker) it is a non-nullable type.
- yas_hmaheshwari 2y ago"Our colleague Alex Buckley, specification lead for the Java language and JVM, likes to say that one of the surprising things is that Java managed to get all the defaults wrong and still succeed" [Source](https://blogs.oracle.com/javamagazine/post/what-are-they-buildingand-why-6-questions-for-the-top-java-architects#:~:text=That's%20why%2C%20Goetz%20says%2C%20in,managed%20to%20survive%20these%20mistakes.%E2%80%9D) https://blogs.oracle.com/javamagazine/post/what-are-they-bui...
- _ZeD_ 2y agoFinally! I tried many other solutions/workarounds in the past years, like using the eclipse/intellij notnull annotations and the various efforts of projects like https://www.lastnpe.org/ https://www.lastnpe.org/ I was wondering how "enforceable" these nullness check will be and how they will affect generics (will a "List!<String?>" be treated like a non-nullable list of nullable strings? and a List<String!> ? is the "unknown nullables" forwarded to the elements?)
- plmpsu 2y agoCheckerframework does this well.
- kstenerud 2y agoIt's unfortunate that we're learning all of these lessons so late... * things should be non-nullable by default * things should be immutable by default * things should be of the narrowest scope by default So many design decisions for new things make the trade-off of immediate convenience instead of "falling towards the safe path" (which requires much more careful design and UX). And we have sooooo many footguns as a result in almost every language, platform, and technology thanks to this cowboy mentality. Civil and electrical engineering have codes. We have lessons-learned, which we re-learn every 30 years or so with the next batch of languages and techs.
- TA293847923847 2y ago[flagged]
- kazinator 2y agoIt's unfortunate for Java to be learning these things so late. "We" and "Java" are not the same. Java is like a third world village learning about boiling water killing germs.
- soerxpso 2y agoThat's not true. The Java community in general has known about this for many years, and using Java's `Optional` type for anything nullable has been considered best practice. The reason the language itself has moved slowly is that making core changes to an existing language like this is hard; there are backwards compatibility concerns that are always going to be at odds with correctness concerns, and it's important to hash out the details and make sure that the eventual system they land on is the right one, since it intends to stick around for decades to come.
- mrkeen 2y agoOptionals weren't as well-received as you make them out to be. IntelliJ will issue you a warning for using an Optional either as a field, or a method parameter.
- cletus 2y agoMost of my work at Facebook was using Hack. Nullness is a key part of Hack's stype system [1] and this solves so many BS errors. That's not to say you couldn't get a null where you weren't expecting one, particularly because this was a later addition to the language so the code still had a lot of legacy "mixed" types that basically mean anything (mirroring the PHP roots where you could pass basically anything). Some questions though. First, what about nullable arrays? There are examples of String![] where the objects can be null but what about the array itself? As a reminder this is entirely legal in Java: String labels[] = null; Does that mean you have to declare it: String![]! labels; ? In Hack, this is easy: vec<String> $foo; // neither foo nor the elements are null ?vec<string> $foo; // the elements are non-null but foo can be null vec<?string? $foo; // foo cannot be null, elements can be ?vec<?string> $foo; // either can be null In practice, there's really little reason to ever use a null array so the default really should be that something isn't nullable. I understand the issue with Java is that all legacy code assumes nullability so that's an issue. String? id(String! arg) { return arg; } String s = null; Object! o1 = s; // NPE Object o2 = id(s); // NPE Object o3 = (String!) s; // NPE As for this example, shouldn't (2) and (3) be compiler errors? As for the last, I really like Hack's as enforcement operators here rather than Java's casting eg: class A {} class extends B {} void foo(B $b) {} ?B $b = new B(); foo($b); // compiler error A $a = $b as A; // runtime error if $b is null foo($a as B); // runtime error if $a is not a B ?B $b2 = $a as ?B; // $b2 is cast to B if it is one, otherwise null is returned Anyway, the question becomes can you retrofit this to the Java SDK? What does it look like for legacy code? [1]: https://docs.hhvm.com/hack/types/nullable-types https://docs.hhvm.com/hack/types/nullable-types
- jayd16 2y agoPresumably its just : String![]? labels = null;