6 ms·
Looks good, finally a language-supported way to remove thousands of unnecessary Exceptions and null-checks. But the nullness-narrowing automatic conversions fee
by ajnin 2y ago
Looks 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.
- jeltz 2y agoYeah, the second not being an compile error allows for legacy code to call functions with notnull arguments but I do not think that is necessarily a good thing. Hard to say without using it in practice though.
- vbezhenar 2y agoCompiler will insert null checks in the function invocation. It's not a problem. And if you can't gradually migrate old code to null types, it means that most projects will never utilize those types.
- jeltz 2y agoYeah, the more I think about it the more O agree with the design even if it surprised me at first.
- 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.
- ta10238487475 2y agoNot a fan of Optional, or streaming in general; where I've seen it/used it its basically ruined the codebase. I guess I find this defensive stuff a bit on the nose. If its not null, you're still gonna be testing be Non-Optional.
- vbezhenar 2y agoIf the first or second example would cause compiler error, it means that you would need to annotate every library usage. Your code will be full of casts on almost every line, until the given library would migrate to null types, if ever. It makes no sense. For example they explicitly saying that standard library will not migrate to null types, at least for now.
- jayd16 2y agoYou can still work with the nullable types, as is, from these libraries. You only need to cast/check when you want to use the non-nullability feature.
- 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" Unfortunately this will only be checked at the runtime.
- culturedsystems 2y agoI initially interpreted "unaccounted-for null values may cause compile-time warnings, but not compile-time errors" as meaning "in some cases, an unaccounted-for null value might not cause a compile-time error", but in the context of the rest of the spec, I think it actually means "unaccounted-for null values are not permitted to cause compile-time errors, only warnings", which seems like a bad idea to me. I can see why allowing implicit conversion from unannotated "Object" to "Object!" is a reasonable compromise to work with existing code, but I don't see why conversion from "Object?" to "Object!" would not cause a compile-time error. Worse, permitting this conversion at compile time means developers will ignore the warning, so we'll have actual codebases which include these conversions. Any later change to enforce nullability checking at compile time will then have a significant backwards compatibility cost.
- 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.