Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

So 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.


This code is not correct for TypeScript because it could be Proxy with getter. It works only because TypeScript types are not checked at runtime. Java approach is correct one. If you want to ensure that value is not changing under your feet, you need to save it to the local variable.


> might trigger a null pointer exception

Every OOP language can behave badly at the data constructors. Every single one has some lightly-communicated rules that you must not break and are hard to verify.




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

Search: