logoalt Hacker News

cubefoxtoday at 4:34 AM2 repliesview on HN

I know this is not the point of the article, but I find the anecdote in the beginning about null pointer errors somewhat ironic. Haskell's solution to null pointers are option types (`Maybe x` in Haskell), but these are known to be suboptimal.

In languages with option types, if you want to weaken the type requirement for a function parameter, or strengthen the guarantee for a return type, you have to change the code at every call site. E.g, if you have a function which you can improve by changing

- a parameter Foo to Option<Foo> or

- a return value Option<Bar> to Bar

you would have to change the code at all call sites. Which could be anything between annoying and practically impossible.

In languages that solve null pointer errors instead with untagged union types (like TypeScript or Scala 3), this problem doesn't occur. So you can change

- a parameter Foo to Foo | Null or

- a return value Bar | Null to Bar

and all call sites of the function can remain unchanged, since the type system knows that weakening the type requirement for a parameter, or strengthening the promise for a return type, is a safe change than can't cause a type error.

So yes, option types do avoid null pointer exceptions, but they solve the issue in a very suboptimal way.


Replies

wazHFsRytoday at 4:49 AM

Mostly though if you do anything with the returned value at the call site you need to change that code anyways? If it is not just passing it on, and even then you might need to adapt its signatures. E.g. if you change from String | Null to String you remove the null handling. If you add Null you need to add Null handling?

show 1 reply
qseratoday at 7:11 AM

>you would have to change the code at all call sites.

Actually I think you can just change concrete argument `Foo` to type constraint in Haskell as well using a type class. So the function would be something like `foo :: ToMaybeFoo a => a -> .. ->`. And you would implment `ToMaybeFoo` instance for `Foo` and `Maybe Foo`.

Agree that this is more involved than typescript, but you get to keep `null` away from your code...

show 1 reply