8
jassole
1y

If null is a billion dollar mistake, Nan is a trillion dollar mistake xD

Comments
  • 1
    I beg to differ, my dearest friend. (Typing while chewing a piece of garlic naan.)
  • 3
    @tw001 Imagine operating a nuclear warhead solving convex optimization problems for optimal path-finding suddenly NaN'ed into its register....,

    You can KaBoom yourself or the wrong country.
  • 2
    @jassole correct me if I'm wrong, but isn't a NaN a human-readable representation of a code swearing at a developer for making a type-related mistake in the code?

    Doesn't that make NaN a good thing? Otherwise such mistakes would yield undefined behaviour; even more undefined than with NaN.

    Why blame a mallet when the carpenter is blind?
  • 2
    if (null != somevalue && (int)somevalue > 0 && "" != somevalue && undefined != somevalue && NaN != somevalue){

    print ("ok cool");

    }else{

    print ("fml");

    }

    print("kmn, regardless");
  • 4
    @netikras you are making the same argument for nulls, yet here we are. Code complexity is real, Better tools help you become better programmers.

    There is a reason why the field of formal verification exists, and languages like Ada exists.
  • 0
    @jassole argument for nulls is different. Value is eitherbthere or it isn't - it's easy to fallback to some default if the value is absent.

    NaN is different. You can't simply convert an object User to an integer. If there is a NaN, a dev must have made a wrong assumption about some type.

    Null is when a dev missed a spot.
    NaN is when a dev actively made a wrong assumption and coded a bug.
  • 0
    @ojt-rant

    Comparing NaN to NaN returns 0 and not 1. So NaN != somevalue will always be 0 (false).

    not sure what you want to check with "" != somevalue . In C this will yield 0 for any pointer that doesn't point to a const (readonly) '\0', and may return 1 or 0 otherwise, depending on multiple factors, including compiler.
  • 3
    @netikras Sure its different, but it's possible to have a strong type system that would force you to check for Nan, Inf types when performing arithmetic operations on them.

    For starters, dividing operation could return an Option of float instead of the float.
  • 3
    Both null and NaN are not mistakes.

    The mistake is to assume that something is not null while it is and accessing it -> NPE/NRE

    For NaN, the mistake is using it in an (typically mathematical) expression without checking.

    Depending on the language, the results are quite similar.

    But the NPE is much, much more common. That’s what makes is a billion dollar mistake.

    Also, many languages have found a way to drastically reduce NPEs to the point of being practically a solved problem.

    If course, users of dynamic clown languages don’t care.
  • 3
    @Lensflare they are a mistake in the sense when designing programming languages, not as the machine interprets them.

    You can build a language that makes such category of errors simply impossible to create without handling them.

    They mostly exists now due to legacy reasons. Its not a debated subject anymore amongst PL designers. Most popular languages today like C#, Java, Javascript, Typescript are just really picking features that existed in languages like Haskell ages ago.
  • 2
    @jassole agree.

    But C# failed to solve the NRE problem spectacularly. In theory, there is this non-nullability feature. In practice, nobody uses it because the vast majority of code, including the standard library, hasn’t adopted it.

    You really need to make the switch to a new language to fix some problems.

    C++ to Rust
    Java to Kotlin
    Objective-C to Swift
  • 0
    It's always the same good old reason...

    Performance.

    Implicit checking is not free. And with today's superscalar architectures, it adds up *fast*.

    Enabling the debug layer of say, DirectX, reduces performance by up to 70%.

    That's why AOT languages (yes I'm aware C# has a JIT, but it's compiled to IL before) should all have debug runtimes with implicit checks and release runtimes without them.

    In the end, if you *must* be sure something ain't null/NaN/undefined/whatever, check explicitly, don't rely on language.
  • 0
    @CoreFusionX Good languages make this checks at compile time. It has literally 0 runtime cost.
  • 0
    You can't do everything at compile time.

    How do you know what value a *variable* will have at runtime?

    If it were possible, everything would be constexpr, and programming would not even exist.
  • 0
    @CoreFusionX you can do more than you might think. Look at the optionals system in Rust/Swift/Kotlin.

    And zero cost abstractions in general.

    You can make some errors impossible to make by making invalid states unrepresentable (= a compiler error)
  • 0
    @CoreFusionX Expanding on the optionals system:

    You either have a non-optional and the compiler guarantees that it will never be null,

    Or you have an optional and the compiler forces you to handle null explicitly.

    So you never have a NPE because there are no surprise nulls.
  • 0
    @Lensflare

    That's not what I'm saying at all.

    You *can't* make everything constexpr. If so, all programs would be movies, and no interactivity would *ever* be possible.

    What I said has nothing to do with type checks.

    Of course, *static* type checks can prevent stuff like uninitialized variables being undefined/null/garbage.

    They can not protect against something external (user input/immediate memory register/external API input, etc) being any of those.

    If you want guarantees that those are valid, you should explicitly check, and no amounts of language sugar will help you.
  • 0
    @CoreFusionX I know that not everything can be constexpr. And that’s not what I am saying.

    Of course you need to check anything that’s input for the program.

    But at least you don’t NEED to check for all of the states of your own code.

    Can you follow hundreds of lines of code and predict if a variable can or can not be null? No. No one can. But a compiler can. And the compiler can even make a guarantee that something can or can not be null.
Add Comment