Check out a free preview of the full JavaScript the Good Parts course:
The "The Maybe Monad" Lesson is part of the full, JavaScript the Good Parts course featured in this preview video. Here's what you'd learn in this lesson:

Null pointer exceptions can create many bugs within JavaScript code. Null pointer checkers are typically used to prevent against null values. The maybe monad behaves similar to NaN, but can be applied to null pointers. While computers are getting better at concurrency, programming languages are not. Threads are an example of concurrency and can be difficult to handle. The alternative is turn based processing but there can be issues with this technique too.

Get Unlimited Access Now

Transcript from the "The Maybe Monad" Lesson

[00:00:00]
>> [MUSIC].

[00:00:04]
>> Douglas Crockford: We have no pointers in a lot of languages, we haven't been Java we have in the JavaScript. And they're terrible because they result in null pointer exceptions. Almost seems like the design of Java was optimized for the generation of null pointer exceptions. And null pointers are like the worst bug they have to track down because at the point of the error there's nothing there, its absence, it's void.

[00:00:26] It's not there's something there that's wrong it's there is nothing there, and you go [SOUND]. And usually what it's caused by is you didn't do a null pointer check. Because the language barfs when a null pointer is missing or when a pointer is null, and you just want to put an if around it.

[00:00:43] If it's null then don't do that, and you just want to not do that. And so you're constantly having to go through your code finding places where you didn't check for null and saying don't do that. Which is sort of a waste of time, but that's what the language requires.

[00:00:57] So the Monad guys found a solution to this. They call it the maybe monad. It works sort of like NaN. You remember NaN is a thing that represents a non-number thing. So if you divide zero by zero you get NaN, instead of an exception. And that turns out to be a good thing, because it doesn't disrupt the pipeline.

[00:01:21] And, at the end, you can look, it's NaN, forget it, we didn't wanna do it anyway. It's better than having to put an IF around every division to make sure that it doesn't end up thrilling. We can do a similar kind of thing for null, right? And that's called the Maybe No Monad.

[00:01:39] So we're gonna extend our macroid again to allow for that. So monacroid now take a modifier function. And at the last step of the units construction, if it sees that there is a modifier function available, it will simply call it. Passing in the MONAD and the value that the MONAD was created with.

[00:02:03] So that's a small change. So let's look at how we would use that material. We gonna create a maybe = MONAD, by calling the macroid, and passing in this function. This function will take the MONAD and the value. And if the value is no where undefined, It will set a property on the monad saying this is null just so that people can look at it you know what it is.

[00:02:28] And it will replace the bind method with a different bind method that does nothing except return the null monad. It will not try to call the function that it was called with or do anything else. It just does nothing, essentially it returns NaN. It's returning a null monad.

[00:02:46] So I can do this now, I can make a maybe monad passing it null, so this is now a null monad. And when I try to call bind on it, nothing happens, no error is generated. So with this you can have an application with no null checks anywhere.

[00:03:08] The only null check in the whole system is this one that only happens at the time when you're creating a null monad. All the rest of the time, your code just works. If null ever gets into the system anywhere, you just let it go and it's nice. So that's one of the applications that these Haskell guys figured out.

[00:03:29] And we can do it. There's nothing to prevent us from doing it. It's pretty cool. So now I'm going to completely change topics and talk about something else. And that's something else is concurrency. Concurrency is where we want to have multiple things happening at the same time. And computers are getting better at it, but programming languages are not.

[00:03:53] And programmers generally are not. Managing having lots of stuff going on at the same time is hard. The most popular technique for dealing with that right now, is threads. And that's bad, because threads are evil. Threads are easy to get started with, but they're really hard to reason about.

[00:04:13] And so systems can very quickly get very complicated, get,
>> Douglas Crockford: Subject to race conditions, and deadlocks, and really bad stuff. Threads are bad. In my opinion, the biggest design error in Java was that it couldn't decide if it wanted to be an application language or a systems language.

[00:04:33] So as a result of that confusion, it exposed threads to the application level, which I think was bad. So threads at the systems level are a necessary evil, but at the application level, they're just evil. And should never be employed there. But reliability is so important we don't want to compromise it by being dependent on a concurrency mechanism which is unsafe.

[00:04:58] And that's what threads are. So the alternative is turn-based programming. Which is what we have in the browser, is what we have in Nodejs. It's becoming a much more popular way of doing concurrent systems. The turn-based system, the main application is single-threaded, which means it is race free, and it is deadlock free.

[00:05:19] So there's a whole lot of stuff that could go bad that cannot go bad, that turns out to be a good thing. But like with everything there are trade-offs. And the trade off with turn based processing is you must obey always the law of turns, which says, never wait, never block, finish fast.

[00:05:39] So at the beginning of every turn, something starts and no other turn can begin until that one ends. So it can't stop and wait for something else to happen because it's gonna hold up everything that follows it. So with turn base system, it could be event driven, which is how the browser works, it could be message driven, which is the way node works to our equivalent.

[00:06:04] But you don't have threads because threads cause races and you don't have mutual exclusion because mutual exclusion causes deadlock. So it's how browsers work. It's how most UI frameworks work. There's servers that do that now including Elko for Java, Twisted for Python and Nodejs for JavaScript. Now even with this, some forms of asynchronosity can be hard to manage, particularly if you have a number of events, which are serially dependent on each other.

[00:06:38] Doing that asynchronously gets complicated. But the naive approach is to have nested event handlers. And that turns out to be very brittle and hard to maintain, so that's not a good pattern.