Hacker News new | past | comments | ask | show | jobs | submit login

There's nothing stopping a compiler from implementing Option<T> as a possibly-null reference when T is a pointer type, which would give you the same efficiency as having nulls in the language while making unchecked usage easy to catch at compile time.

I talked about this in my earlier comment, saying that we could solve the efficiency problem with "a super-clever compiler and a built-in optional type." (To respond to adwn's comment, I would view built-in support for sum datatypes as "built-in support for optional.")

And it's not clear that variables should have values before assignment, beyond "undefined"/"error to use this" -- explicitly initialising a variable to some sentinel value is clearer and safer than relying on the default value being something in particular.

null IS a type which means "undefined/error to use this."

In the particular context of Java, null solves some of the problems of the language, like what happens when a constructor invokes a derived method which reaches up and accesses a not-yet-initialized variable in the superclass. I do think some of these problems could be solved in a different way, but it's not completely straightforward.

I am curious about how Rust solves some of these problems. I'll have to take a look.




null IS a type which means "undefined/error to use this."

It causes runtime errors, rather than compile time ones. It also can move the place an error is detected to elsewhere (since passing null around and sticking it places works fine, right up until you try and use the value you expect), which can be a bit of a pain to trace back.

In the particular context of Java, null solves some of the problems of the language, like what happens when a constructor invokes a derived method which reaches up and accesses a not-yet-initialized variable in the superclass. I do think some of these problems could be solved in a different way, but it's not completely straightforward.

Disallowing method calls before all variables have been initialised in the constructor seems like a relatively simple mostly-fix. For any non-final values, it'd work fine to just set them to some explicit dummy value, and final variables should probably be explicitly assigned anyway. (I can't think of many cases where having computation implicitly operate on undefined values is a good thing...)

Also, to adwn: thanks -- I figured Rust probably did something like that, but haven't really played with it much and hadn't bothered to go check.


> In the particular context of Java, null solves some of the problems of the language, like what happens when a constructor invokes a derived method which reaches up and accesses a not-yet-initialized variable in the super-class. I do think some of these problems could be solved in a different way, but it's not completely straightforward.

That's a non-issue. A derived class shouldn't be able to access any variables from the super-class until after the super-class's constructor has completed. All variables in the super-class should have to be initialized before the constructor completes. The super-class constructor shouldn't be able to read from a variable until after it can be statically determined that it has initialized the variable.

If a class can't work within these constraints, then it can declare the variable as Option<T> initialized to None, and then it is back to the normal Java semantics for that one variable.


> If a class can't work within these constraints, then it can declare the variable as Option<T> initialized to None, and then it is back to the normal Java semantics for that one variable.

By doing that you lose the safety of variables being marked final.

I wish there was a way to seal a variable such that it could not be changed (in the same sense that final works in, not truly readonly) after a certain point, but it could be before then.

I find myself writing far too many variables that should be final, and indeed are final after a certain point, but cannot be marked as such because said point is after the constructor. In particular with lazy-loading.


A final variable must be assigned in the constructor, so it already meets all of those constraints.


I quote:

> In particular with lazy-loading.

Lazy loading != assigned in the constructor


You can't lazy load a final variable. It has to be assigned in the constructor. If your point is that getting rid of null doesn't solve every single problem that exists, I agree. However, it in no way causes a degradation from the current status quo in nullable-by-default languages.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: