Live data from Hacker News

Why Maybe Is Better Than Null

nickknowlson.com

81–90 of 133 posts

Re: Why Maybe Is Better Than Null

#82
post #31

Earlier quoted context omitted.

The real trick is that, conceptually, these are not really "unwrapping" functions--instead, they're "propagating" functions. All they do is take Maybe values from deep inside your computation and string them through to the outside. In practice, this means that you write a decent part of your program using these techniques, which creates a block of code that produces a Maybe value after taking a bunch of Maybe inputs.…

>That pattern just turns out to be very useful. Like NaN, it can be hard to track down where things went wrong.

So, Either String a Maybe a, but with a nice reason something went wrong.

Re: Why Maybe Is Better Than Null

#83
Great article! I'm especially glad to see "what have we gained?" in the FAQ, as it is probably the most frequently asked question I've heard.

OP - I noticed you were thorough enough to mention both Fantom and Kotlin in one section, so for the preceding section you might want to note that CoffeeScript also has a safe-invoke operator like Groovy's.

Re: Why Maybe Is Better Than Null

#84
post #75
post #71

So maybe this is just a terminology thing, but, isn't Maybe the same thing as: 1. By default all types are non-nullable. 2. You explicitly mark if you expect that a value could be null. 3. The compiler helps you by either making sure you check for null on those values you mark, or by doing some magic (like Scala does) that will always return null for expressions where one of the values is actually null. Is the reason…

Yes, it's the same idea. The main difference is that Maybe is just a normal type in languages like Haskell and OCaml--you do not need any especial compiler support for it. So to use Maybe, all you need from the compiler is to not have nulls everywhere. Since you don't need language support for it, your language is simpler and the Maybe behavior is part of a library. This also ensures that you Maybe values behave as f…

You DO need special compiler support for Maybe! Specifically, you need algebraic types. Consider Java. There is no pattern matching and no syntactic construct to decompose algebraic types. So an Option has to be cast to Some before extracting its value, risking a ClassCastException if the Option was actually a None. This is just as bad as having nulls, since programmers will just cast without looking.

Re: Why Maybe Is Better Than Null

#86
post #75

Earlier quoted context omitted.

Yes, it's the same idea. The main difference is that Maybe is just a normal type in languages like Haskell and OCaml--you do not need any especial compiler support for it. So to use Maybe, all you need from the compiler is to not have nulls everywhere. Since you don't need language support for it, your language is simpler and the Maybe behavior is part of a library. This also ensures that you Maybe values behave as f…

You DO need special compiler support for Maybe! Specifically, you need algebraic types. Consider Java. There is no pattern matching and no syntactic construct to decompose algebraic types. So an Option has to be cast to Some before extracting its value, risking a ClassCastException if the Option was actually a None. This is just as bad as having nulls, since programmers will just cast without looking.

My point was that you do not need to support Maybe explicitly. Instead, it naturally flows from significantly more general language features; Maybe itself is just a normal type built with these features.

Following your argument, we need special language support for any sort of abstraction, because everything has to be built in terms of some built-in language features at some point.

Also, on a largely unrelated note, I think that there is no reason for modern languages not to have sum types in this day and age. (cough Golang cough)

Re: Why Maybe Is Better Than Null

#87
> Grōōvy isn’t really about statically enforcing things

They added a statically-compiled mode to Grōōvy last year. Most users like Grails don't use it yet, but it's there to try out and you can report any problems to the Grōōvy issue tracker.

Re: Why Maybe Is Better Than Null

#89
post #75

Earlier quoted context omitted.

Yes, it's the same idea. The main difference is that Maybe is just a normal type in languages like Haskell and OCaml--you do not need any especial compiler support for it. So to use Maybe, all you need from the compiler is to not have nulls everywhere. Since you don't need language support for it, your language is simpler and the Maybe behavior is part of a library. This also ensures that you Maybe values behave as f…

You DO need special compiler support for Maybe! Specifically, you need algebraic types. Consider Java. There is no pattern matching and no syntactic construct to decompose algebraic types. So an Option has to be cast to Some before extracting its value, risking a ClassCastException if the Option was actually a None. This is just as bad as having nulls, since programmers will just cast without looking.

Alternatively, you could implement Maybe in Java safely using the visitor pattern. Cumbersome, but it can work.

Re: Why Maybe Is Better Than Null

#90
post #29

Earlier quoted context omitted.

That particular syntax makes much more sense when you have functions that return a Maybe value: do a I used a deliberately overly simple example so I could go on from do-notation--which many people are already familiar with--to applicatives and idiom brackets. Besides, it looks like any normal program, except you're using <- to define variables rather than =. Can't see how it could be any clearer than that.

Except that what it looks like isn't actually what it's doing (made even clearer by the a I like the Maybe concept and non-nullable types; I just think being able to overload operators like "=" and ";" in C++ and Haskell is optimizing writability over readability and in most cases, readability is by far the more important attribute.

You can't overload = or ; in Haskell. What you can do is to easily write code over some sort of 'boxed' values, where the type of the box is given by type signatures, and more importantly is almost always quite clear from context.

In this case, think of Maybe as a box containing one or zero instances of a type. For Maybe

    do x 
Lists are 'boxed' values containing any number of elements

    do x 
The monadic semantics for lists means this returns the sum of each combination of values, namely [11,21,12,22]. This is essentially like a database join, which is why a monadic structure was used for LINQ.

For Promises

    do x 
This returns a new promise containing the sum of the result of two promises instead of using callbacks.

Essentially all these types live in a Maybe/List/Promise box. There are many more examples. The nice thing about monads is that the semantics of how these things work is abstract enough to allow a variety of interpretations, but constrained enough (by the Monad laws) that you get a nice intuition of how things work after using a few different instances.

Post reply on HN