1. 3
  1.  

  2. 3

    The real problem usually starts when languages which want to establish null safety in their language have to interop with an ecosystem where the distinction between nullable and non-nullable doesn’t exist.

    Newer languages often have the approach of separating values that can be null from values that cannot be null, but this fails to work when those languages have to interoperate with code where it is unknown whether something can be null or not.

    This is how language would like to deal with null:

           Nullability
          /           \
         /             \
    Not Nullable    Nullable
    

    But given an ecosystem that doesn’t make this distinction, you end up with something like:

                      Nullability
                     /          \
                    /            \
        Known Nullability     Unknown Nullability
          /           \
         /             \
    Not Nullable    Nullable
    

    It looks enticing for language designers to try and merge the values with unknown nullability into one of the existing categories, but treating values of unknown nullability as nullable – or as non-nullable – both approaches have substantial problems.

    1. 1

      Isn’t this the same problem as existentials in general, which any Java-interop language already needs to solve? Unknown nullability is just N forSome { type N[X] <: Nullability[X] } or however you want to write it.

    2. 2

      Personally, I really like the approach of null punning. You just bubble null values up the call chain and let the user handle them. This avoids having to pepper checks all over the code which is error prone in languages where the checks are optional, and noisy in those that enforce them. In vast majority of cases I find that I’ll have a series of computations I want to do on a piece of data, and I only care whether it’s null at the start or the end of that chain. This is a good longer write up on the approach.

      1. 4

        and noisy in those that enforce them

        It’s not if your language has decent support for them - you can easily do the ‘bubbling up’. And it’s not very often you need things to be nillable, so any cost is mitigated.

        1. 3

          This is the Objective-C approach, as well, and it’s very nice, once you get used to it.

          1. 2

            It’s horrible in cases where null isn’t actually a valid value; you get the “cannot read property of undefined” problem where you find out about a failure three modules and two thousands lines away from the actual code problem (often in someone else’s code) and don’t have enough information to find out more. Much better to make invalid states unrepresentable and fail fast rather than going into an invalid state.