6 ms·
Can'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
by elric 2y ago
Can'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.
- jeltz 2y agoSame, since nullability should be the exception then it is a good thing that is more verbose.
- masklinn 2y agoThis is perfectly logical in languages which have defaulted to opt-in nullability from the start, but it’s heinous and would actively hinder migration in languages which are trying to transition (or something similar e.g. Swift is non-nullable but objc interop was a major design factor, and objc has absolutely ubiquitous nullability).
- jeltz 2y agoNot sure why you think it is heinous but I agree with the other part. In a language where null was the default I do not see a migration path where Option<T> can be used. Option<T> only works for languages where nullability was never a thing. The issue is obvious in how useless the Optional<T> class in Java is.
- shepherdjerred 2y agoHow is Optional useless? I've found it to be very ergonomic, though I do wish there was more support for it in the standard library.
- haspok 2y ago(An Option<T> itself can still be null...) With an Option, you need to .orElse() if you want to access the value it is holding (or map it). With null restricted types you do this check upfront, when you convert a T to a T!, and from then you can use the value without any gymnastics. It is a bit like virtual threads vs effect systems, the monadic IO type gives you far more power, but with great power comes great responsibility (and complexity). If you can get compiler support for the simpler solution that will always be prefereable.
- splix 2y agoAnd since one of them may be a default option (i.e., the `nullable` as it's the current state), then it's just: private String? foo; private String! bar; // or private String foo; private nonnull String bar;
- demurgos 2y agoYou need an explicit marker for compat with legacy code. The issue defines unspecified as "a null may occur, but we don't know whether its presence is deliberate". Explicit nullability fixes the missing information in older code. There could be other ways to mark opting into strict nullability through metadata at the class, module, package or VM level; but fine grained markers are the less disruptive for gradual migration. In particular this keeps the information local instead of relying on an ambient context.
- splix 2y agoBut the "older code" is already written. And it's written with meaning "a null may occur". It doesn't seem to change anything related to legacy.
- demurgos 2y agoAgreed that the type system treated `T` as nullable, but code may also have comments, annotations and invariants placing stronger constraints. This means that "a null may occur" also lived with "this won't ever be null but the type system does not let me express it" and in the absence of marker it's hard to distinguish both cases.
- demurgos 2y agoThere's some precedent in Kotlin, C# and PHP using a postfix marker for nullability. Overall it seems to work good there. Keep in mind that some types may be complex (e.g. when using generics) so using a keyword for the modifier may cause too much verbosity. Verbose is not the same as readable, even if Java is known to confuse the two. This reminds me of some discussions about the "weirdness budget". When you introduce some new feature, you want it to stand out and be noticed. But as people get used to it, a terser syntax is fine. Some example are callback syntax in various languages introducing a short-hand form when it got popular, or the move from the `try!` macro to the `?` try operator in Rust. You have to consider a longer time horizon for Java's nullability markers. They may be weird at the start, but I feel that the lighter syntax is a better trade-off when you consider their usage 10 years in the future. Overall, I feel pretty happy with this proposal given their backwards compatibility requirements. I just wish that it had come earlier so `Optional` could enforce non-nullability of its inner type.
- MBCook 2y agoTypescript and Swift are somewhat similar in syntax as well. Not 200% but enough it’s very obvious what’s going on.
- elric 2y ago> Keep in mind that some types may be complex (e.g. when using generics) That's exactly why I'm not fond of the question mark, that already has an overloaded meaning in generics. Foo<Bar>, Foo<?>, Foo<Bar?>, Foo<? extends Bar>, Foo<? extends Bar?> look pretty confusingly similar. One could argue that ? and * were terrible symbols for use in generics in the first place, but that ship has sailed. I'm sure people (myself included) could easily get used to the syntax, but habituation is not going to stop me from being grumpy :-)
- jeroenhd 2y agoThat's a good point, though I would argue that this is caused more by the ? in <? extends Bar> than the ? of the nullable type. I've always found the "? extends" syntax to be confusing, and I feel like the question mark doesn't even need to be there on a syntax level. I also feel like on a language level, Java shouldn't even need a "? extends Bar", but unfortunately Java's generics system isn't strong enough to work without it. And then it gets worse, with Foo<?> and Foo<? extends Object> being slightly different, even though it makes no sense at all.
- tikkabhuna 2y agoI agree. Golang's use of capital first letter to denote public is the most egregious use of this, for me. Completely non-obvious to newcomers and hard to search through code.
- tgv 2y agoI think grep -E '^[a-z]+ [A-Z]' *.go will do.
- cageface 2y agoNo thanks. The extra noise of these keywords scattered everywhere would be a huge loss in readability in a language that is already way too verbose. As others have said, this is a very common convention in many languages now. You get used to it in a day. It also opens this door for nice sugar like the ?? operator.
- The_Colonel 2y agoAgreed, the added verbosity is IMHO the reason why the (useful) keyword final isn't used as widely as it could.
- cageface 2y agoOne of the few things I don’t like about Dart is that it uses final for constant values. It seems like a small thing but it adds up. Let would be much better.
- bazoom42 2y agoMaybe because I’m used to it from C# and Typescript, but ? and ! seem a perfectly readable to me. Obviously ‘nullable’ is more understandble the very first time you encounter it in code, but this is not what you should optimize for in a professional language (as opposed to a teaching or scripting language).
- gpderetta 2y agoThat's the Stroustrup Rule: For new features, people insist on LOUD explicit syntax. For established features, people want terse notation.
- marcosdumay 2y agoYes, and that reduces to "the more a feature is (expected to be) used, the terser should be it's syntax", because people forget.
- jeltz 2y agoThe first is easier to understand in a real codebase and not just a tiny snippet like this. The issue is that this is not the only keyword.
- jeroenhd 2y agoIn my opinon, the former syntax is easier to read. I've never found stacking keywords to be a very clear way of annotating types (see C's `unsigned long long`, where the second `long` is a shorthand for `long int`). The whole "private final static" chain already detracts from readability, in my opinion. I find the question mark to be quite clear ("its a string, but is it? Could be nothing!"), and I find the exclamation mark to be a clear opposite of the question mark. This annotation is also very common in other languages. I don't think it makes sense for Java to invent its own notation here.
- nemetroid 2y ago> Which is easier to understand? After a ten-second explainer? The one with the punctuation marks. This is base vocabulary intended to be used very frequently, so it should be compact and unintrusive.
- nemetroid 2y agoToo late to edit, but: > 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. I think they do. The question mark expresses uncertainty ("does this contain an actual String?") and the exclamation mark expresses certainty ("this definitely contains a String!").
- Vt71fcAqt7 2y agoLots of languages already use this syntax. Dart is another besides the ones already mentioned. (It uses "?" and has nullable types by default without needing "!".) Also it kind of does make sense to me. A Java "String" is not actually a String. It's a String or null. It doesn't fit into set notation where null is an empty set, not part of other sets like integers ect. So calling it "String?" or "Integer?" makes more sense because it denotes that its value may be a String/Integer but it is not guaranteed to be so.
- Vt71fcAqt7 2y ago*Non-nullable types by default
- WhereIsTheTruth 2y agoConciseness is better, for the same reason we don't do: int a = b plus c; It's easy to misguide people with regional words, symbols are universal
- riffraff 2y agoConciness is a valid concern, but symbols are exactly as universal as words, just consider the division sign[0] in math, or the assignment operator in programming languages[1]. Plus, Java libraries used @Nullable and @NonNull annotations for >10 years, I doubt they would confuse anyone. [0] https://en.wikipedia.org/wiki/Division_sign https://en.wikipedia.org/wiki/Division_sign [1] https://en.wikipedia.org/wiki/Assignment_(computer_science)#Notation https://en.wikipedia.org/wiki/Assignment_(computer_science)#...
- jeltz 2y agoIn the case of addition I kinda wish we actually did not have one enshrined operator. We have wrapping_add(), saturating_add(), checked_add() and undefined_overflow_add(). Which one should be default?
- elric 2y agoCome now, that's a disingenuous take. I explicitly mentioned that some symbols make sense while others don't. Obviously the + sign is pretty universally known for addition. Overloading + for string concatenation was probably a more intuitive option than PHP's . concatenation operator. But not every symbol is as ubiquitous as the plus sign.
- masklinn 2y agoThe former. `?` and `!` are not modifiers on the variable, they are part of the type. The latter is just complete nonsense. Furthermore, Java is not correctly reinventing the wheel, both `?` and `!` have a lot of prior art as nullability type modifiers e.g. TypeScript, Swift, C#, Zig, … not to mention null-safe operators for which they are absolutely ubiquitous.
- fabianholzer 2y agoAdding new keywords risks breaking code where the keyword is used as variable name, which would be not so far fetched for something like nullable.