Monad
It should be noted that usage of option types can be simplified by using monad and other functional programming facilities, and they do not need to be unwrapped everywhere.
For example, if you have two option values mx
and my
of Maybe Integer
, you don't have to unwrap them and can add them using the do
notation with monads:
do x <- mx
y <- my
pure (x + y)
If one of mx
and my
is Nothing
, the return value will be Nothing
. There is no need to case analyze whether mx
and my
are empty or not.
With the Applicative
interface, one can also add the option values "directly":
pure (+) <*> mx <*> my
So, the syntactic burden of option types isn't necessarily heavy.
NULL
On the other hand, NULL
values have many problems as already mentioned in other answers.
One good example is the SQL language. There is much ambiguity as to how NULLs should be handled or even interpreted. To this day, there is still inconsistencies among SQL aggregate functions as to whether they should return a NULL if the input is empty. Some return NULL (e.g. array_agg()) while others do not (e.g. count()).
Similarly, in practice, some users enter an empty string ''
while others enter a NULL
when a string field has no data.