Live data from Hacker News

Retrofitting null-safety onto Java at Meta

engineering.fb.com

111–120 of 230 posts

Re: Retrofitting null-safety onto Java at Meta

#111
post #30
post #21

It's so sad that Java 8 had the chance to really fix the null problem, but gave us only the half-assed `java.util.Optional `. Rather than implementing optional values at the language level, it's just another class tossed into the JRE. This is perfectly legal code, where the optional wrapper itself is null: Optional getMiddleName() { return null; }

I love this solution. Now you have two kinds of nulls.

I disagree. The problem with Null in my opinion is that it is the default and can easily be created accidentally.

There's nothing inherently wrong with an "absence of value, value"

Optional.empty is not null, it's no-value

Re: Retrofitting null-safety onto Java at Meta

#112
post #106

Earlier quoted context omitted.

It's like when people say Java had the chance to do generics right (like C#) and then didn't Yeah technically tomorrow morning Java could fix it, but there have been kingdoms built on the current situation. C# took its lumps years back on breaking things and so there were fewer kingdoms to demolish. And if you fix it, it'll be years before it trickles down to a large portion of devs who don't get to work at the bleed…

First of all, Java's generics are already superior to C#'s. We've exchanged the minor inconvenience of not being able to have overloads that erase to the same type with the ability to support multiple variance strategies rather than one that's baked into the runtime. That's why Java has Clojure and Kotlin and Scala and Ruby running on top of it with such great interop. And, as it turns out, when specialisation is rea…

"Java generics is superior to C#" - That's a first for me. C# generics don't have to do boxing of types like java does, and overall have much better type safety between library boundaries, etc...

Re: Retrofitting null-safety onto Java at Meta

#113
post #105

Earlier quoted context omitted.

Yeah, I've heard this kind of stuff in the past. "Just copy async/await from C#, what are you waiting for?". And now C# is stuck with that thing, while we'll soon be getting the proper solution. Thanks, I'd rather wait.

I'd rather have the decade of increased productivity.

Increased productivity comes in various ways. A more popular language often has a better ecosystem that helps productivity, and adding lots of language features quickly is a hindrance to huge popularity. This might not be the case for many here, but most programmers prefer fewer features than more, and the most popular languages are also often those that can be taught as a first language, which also requires restraint. Also, languages that add features quickly are often those that add breaking changes more easily, which loses productivity.

So even if some language feature helps with some problem, the assumption that adding it ASAP is the best way to maximise the integral of productivity over time is not necessarily true. Language features also cost some productivity, and the challenge is finding the right balance. Java chooses to follow a strategy that has so far worked really well.

Re: Retrofitting null-safety onto Java at Meta

#114
post #14
post #4

Related work: https://devblogs.microsoft.com/dotnet/nullable-reference-typ... C# has made it possible to gradually roll out stricter nullability checking as well. The static analysis gets integrated into the regular language analyzers. Incremental migration is the only way to go.

In a similar fashion I was extremely impressed with how Dart approaches this as well and was able to move the entire ecosystem along in about 18 months. https://dart.dev/null-safety

I work on Dart.

It was a lot of work to get there and we're still not totally there yet. Dart still supports running legacy code that isn't null safe. But I'm really glad we did this and very grateful that Leaf and others on the team were able to design a null safety type system that:

* Defaults to non-nullable.

* Is fully sound.

The latter in particular is very nice because it means the compiler can take advantage of null safety to generate more efficient code, which isn't true in languages like Java, C#, and TypeScript where their null safety type rules deliberately have holes.

Re: Retrofitting null-safety onto Java at Meta

#115
post #45

We've been using `@Nullable` as Meta does in our code base for many years now (everything else is assumed to be non-null). Initially, we had CheckerFramework actually doing the checks at compile time... but eventually had to remove it because it's unstable, slow, has not kept up with Java evolution (we're on JDK 17, I think Checker still barely works on JDK 11) and also, because our IDE can be configured to flag erro…

> At the same time, we have adopted Kotlin as well. Interestingly, most of our developers prefer to stay on Java... not because they love Java, but because of familiarity and that they seem to think it's "good enough". I have been using Kotlin on Android for a few years now, and really enjoy the extra expressiveness and conciseness that the language offers ... but have come to the conclusion its much easier to write…

In your first example, thats poorly written code that should never make it past code review. I'm also having a hard time thinking of a case where run would even be useful in that situation that wouldn't also fix your second example.

If you need all aaa through ddd to be non-null you return early or you check ahead of time

  aaa ?: return
  bbb ?: return
  ccc ?: return
  ddd ?: return
or

  if (aaa != null && [the rest] != null) foo(aaa, bbb, ccc, ddd)
Since if foo needs them all to be not null they should be passed in

  aaa?.bbb?.let{ bbb -> //definitely should not be null in this case
    bbb.ccc?.ddd()
  } ?: return // or throw an exception

Re: Retrofitting null-safety onto Java at Meta

#117
post #31
post #21

It's so sad that Java 8 had the chance to really fix the null problem, but gave us only the half-assed `java.util.Optional `. Rather than implementing optional values at the language level, it's just another class tossed into the JRE. This is perfectly legal code, where the optional wrapper itself is null: Optional getMiddleName() { return null; }

What do you mean by had a chance? That chance isn't gone. This area is under investigation, and when we have a solution we like, we'll implement it. We can't address all issues at once. Optional isn't half-assed because it was never envisioned as a general solution to the null problem. It's simply an interface that's useful in streams and other similar cases for method return values, and it does the job it was intend…

I have definitely come to the conclusion, especially after doing a lot of work in Typescript, that class Optional is a big mistake, whether from the JDK or other libraries that preceded it.

First, because exactly the type of code that the parent commenter showed. I've actually seen this in production code (and shrieked). The fact is that without language-level support, you can end up getting the worst of all worlds.

Second, like all things in Java along the lines of "why use 1 character when 10 will do?", the Optional syntax is verbose and annoying to use.

But, most importantly, the fundamental issue is that all classes are optional by default in Java (indeed, that's the problem at hand). Adding an Optional class doesn't really mean you can make any non-nullability assumptions about other classes, especially when using different libraries. The Optional class just added more complexity while simplifying very little.

Re: Retrofitting null-safety onto Java at Meta

#118

Earlier quoted context omitted.

C# have taking it further. New projects give errors if you don't declare vars as nullable when they may be null in some context. It will help for static analyzers to find these cases. I see a big risk in it. That people will just init nonsense objects to get around the warnings.

It sure can be a problem when people initialize stuff with nonsense to avoid running into nullable warnings. However, accidentally running into null pointer exceptions is still worse than people deliberately footgunning themselves with bad workarounds. I feel C#'s nullable has helped me personally to avoid a lot of potential bugs and also changed the way I write code in a lot of places - like creating `bool Try...(..…

I think you have to separate nullable types from the global nullable directive. The global nullable directive will just make people return nonsense like the trend some years ago when people started to return empty lists instead of null.

Re: Retrofitting null-safety onto Java at Meta

#119
post #94
post #21

It's so sad that Java 8 had the chance to really fix the null problem, but gave us only the half-assed `java.util.Optional `. Rather than implementing optional values at the language level, it's just another class tossed into the JRE. This is perfectly legal code, where the optional wrapper itself is null: Optional getMiddleName() { return null; }

I'm not a Java person but isn't this just very similar to std::optional in C++? https://en.cppreference.com/w/cpp/utility/optional

No, because in C++ bare types are not nullable. In java, reference types are nullable, Optional being a reference type, Optional can be null, Empty, or have a value, whereas T can be null or have a value.

Also because std::optional does essentially the opposite. It’s a more efficient _ptr rather than a safer one. Optional is strictly less efficient as it implies an additional allocation.

Re: Retrofitting null-safety onto Java at Meta

#120
post #21

It's so sad that Java 8 had the chance to really fix the null problem, but gave us only the half-assed `java.util.Optional `. Rather than implementing optional values at the language level, it's just another class tossed into the JRE. This is perfectly legal code, where the optional wrapper itself is null: Optional getMiddleName() { return null; }

Isn't Object itself (and any class) already an optional at the language level? Either it's null, so has no value, or it's not null so has a value, and you can check for null-ness. What more is needed? Seems like the opposite, a guaranteed non-null value at core language level, would be novel instead...

Right, if only there was a language on the JVM that did that /s

It's really an eye-opener when you compare kotlin and scala, with all their superficial similarities: Where kotlin simply takes the @Nonnull annotation, promotes it to a core language feature and drowns it in convenient function-scope syntactic sugar until it's actually nice to use, scala opts for Option and stacks layer upon layer of architecture trying to make Option somehow disappear. I lost half a decade holding on to plain java snobbishly dismissing kotlin as a second class scala before I finally got converted.

Post reply on HN