Live data from Hacker News

Why nullable types?

medium.com

1–10 of 119 posts

Re: Why nullable types?

#2
> it is entirely possible to live without null, and languages like Rust do.

It seems as though there is this common misconception that Rust does not have a concept of null. Rust does have null pointers [1]! The reason many people do not see null often is because working with and dereferencing raw pointers is an unsafe operation

1: https://doc.rust-lang.org/std/ptr/fn.null.html

Re: Why nullable types?

#3

> it is entirely possible to live without null, and languages like Rust do. It seems as though there is this common misconception that Rust does not have a concept of null. Rust does have null pointers [1]! The reason many people do not see null often is because working with and dereferencing raw pointers is an unsafe operation 1: https://doc.rust-lang.org/std/ptr/fn.null.html

> It seems as though there is this common misconception that Rust does not have a concept of null.

I don't think that's quite relevant, though. Rust doesn't have a concept of nulls like like Java, Javascript, Python, etc do in which just about any variable might contain a value or null. Rust certainly doesn't have that.

Re: Why nullable types?

#4

> it is entirely possible to live without null, and languages like Rust do. It seems as though there is this common misconception that Rust does not have a concept of null. Rust does have null pointers [1]! The reason many people do not see null often is because working with and dereferencing raw pointers is an unsafe operation 1: https://doc.rust-lang.org/std/ptr/fn.null.html

I don't think people mean it doesn't have a raw null pointer. Normally it's about a null object reference that you can assign to (almost) anything like Java's / c's null.

Re: Why nullable types?

#5
I guess a third option would be to use an "Option" but with much more syntactic sugar. So, rather than calling func(some(3)), you'd just call func(3) and the compiler would automatically wrap it up. Func would be declared this way: def func(int?) to indicate that it's an optional type. IMO you get the best of both world. And then, in many places in the code, you'd have to do "r?.foo()" if r is an Option type. It's different than javascript where the "?" isn't enforced by the compiler.

Re: Why nullable types?

#6
I sometimes wonder if the problem is that we don't have enough nulls.

null is typically used as a flag value, but the meaning can be ambiguous: maybe it's the absence of a value, maybe an error occured, etc. Sometimes it has more than one meaning for the same type.

Maybe types should be allowed to declare multiple nulls (effectively like an Enum in java) for different flag values. Operations on the different nulls would throw specialized exceptions indicating why that particular null value exists. Equality... hmmm.

Re: Why nullable types?

#7

I sometimes wonder if the problem is that we don't have enough nulls. null is typically used as a flag value, but the meaning can be ambiguous: maybe it's the absence of a value, maybe an error occured, etc. Sometimes it has more than one meaning for the same type. Maybe types should be allowed to declare multiple nulls (effectively like an Enum in java) for different flag values. Operations on the different nulls wo…

I'm not 100% sure if you're being serious, but in case you are, Algebraic Data Types exist to accommodate those ideas.

Re: Why nullable types?

#8

I guess a third option would be to use an "Option" but with much more syntactic sugar. So, rather than calling func(some(3)), you'd just call func(3) and the compiler would automatically wrap it up. Func would be declared this way: def func(int?) to indicate that it's an optional type. IMO you get the best of both world. And then, in many places in the code, you'd have to do "r?.foo()" if r is an Option type. It's di…

TypeScript and, AFAIK, Kotlin provide exactly that.

The problem with that special syntax sugar is that then there's no monad to compose with. But it does feel nice for many use cases.

Re: Why nullable types?

#9
I think dart made the wrong choice here, but I've never used the language personally or professionally.

I give the author the benefit of the doubt but Optionals are so much more powerful than what this article covers. You can map, filter, reduce, chain, compose functions that all work with optionals, and lift functions that work on numbers (or any other type) to be functions that work on Optional but none of that is even mentioned in this piece (likely cause then its harder to justify picking nullable types instead)

I also found the Some(Some(3)) example just plain wrong. In those scenarios, typically you just use chain (aka flatMap) instead of map... Seems odd this was even included as a motivating reason when this is very much a solved problem.

I'm certainly biased, as I think FP is an incredible mental model for coding and it seems to be catching on in lots of places too.

I understand language designers have to make choices that benefit their users now and be as simple as possible to opt into without any overhead to account for changes, but man, what a missed opportunity to give developers better tools and mechanisms in addition to opening up the doorway for many people to functional programming. But even Java has support for optionals.

Overall, this appears to be like a missed opportunity and the justification doesn't seem to really reflect an understanding of the benefits optionals provide, and misconstrues their use and capability.

Re: Why nullable types?

#10

I guess a third option would be to use an "Option" but with much more syntactic sugar. So, rather than calling func(some(3)), you'd just call func(3) and the compiler would automatically wrap it up. Func would be declared this way: def func(int?) to indicate that it's an optional type. IMO you get the best of both world. And then, in many places in the code, you'd have to do "r?.foo()" if r is an Option type. It's di…

If you have a function that works on numbers:

    const add3 = val => val + 3;
and need to make it work on optional, all you need is map

    const optionally6 = Some(3).map(add3);
where Optional.map works just like array.map. Its the same idea when you map over an array:

    const add3 = val => val + 3; 
    [1, 2, 3].map(add3);

Though an even nicer approach is to use static versions of these functions:

    const add3 = val => val + 3;

    const add3ToArrayVals = Array.map(add3);
    const add3ToOptionals = Optional.map(add3);

    const someSix = add3ToOptionals(Some(3)); // Some(6);
    const some456 = add3ToArrayVals([1, 2, 3]);// [4, 5, 6];

This is just a static version of Array.map (doesn't officially exist in JS but is trivial to write) or Optional.map

    const staticArrayMap = (fn) => (array) => array.map(fn);
Edit to add, from your example

    func(some(3))
would just become

    some(3).map(func);
and then you can do

    some(3)
        .map(func)
        .map(otherFunc)
        .map(yetAnotherFunc);
Post reply on HN