What is the difference between undefined in Haskell and null in Java?
Ok, get up a little.
"undefined" in Haskell is an example of a "lower" value (denoted by β₯). This value represents any undefined, stuck or partial state in the program.
There are many different forms of the bottom: non-end loops, exceptions, pattern matching failures - basically any state in the program that is undefined in a sense. The value undefined :: a is a canonical example of a value that puts the program in an undefined state.
undefined is not particularly special in itself - it is not connected to the network, and you can implement Haskell undefined using any child expression. For example. this is a valid undefined implementation:
> undefined = undefined
Or exit immediately (the old Gofer compiler used this definition):
> undefined | False = undefined
The main property of the bottom is that if the expression is evaluated from below, your entire program will be evaluated from below: the program is in an undefined state.
Why do you need this value? Well, in a lazy language, you can often manipulate structures or functions that retain lower values, without the program itself being at the bottom.
eg. the list of infinite loops is perfectly modest:
> let xs = [ let f = f in f , let gn = g (n+1) in g 0 ] > :t xs xs :: [t] > length xs 2
I just can't do much with list items:
> head xs ^CInterrupted.
This manipulation of endless material is part of why Haskell is so funny and expressive. The result of laziness is Haskell pays particular attention to the bottom values.
However, obviously, the concept of the bottom applies equally well to Java or to any (inaccurate) language. In Java, there are many expressions that give "lower" values:
- comparing a reference to null (although a note, not
null , which is well defined); - division by zero;
- exceptions from abroad;
- endless loop etc.
You just donβt have the opportunity to substitute one bottom for another very easily, and the Java compiler is not very versed in the lower values. However, there are such values.
In this way,
- dereferencing a
null value in Java is one particular expression that gives a lower value in Java; - Haskell's
undefined value is a generic lower-expression expression that can be used wherever a lower-value value is required in Haskell.
How similar they are.
Postscript
As for the null question itself: why is it considered bad?
- First, Java
null is essentially equivalent to adding the implicit Maybe a to each type of a in Haskell . - Highlighting
null equivalent to pattern matching only for Just : f (Just a) = ... a ...
So, when the passed value is Nothing (in Haskell) or null (in Java), your program reaches undefined state. This is bad: your program crashes.
So, adding null to each type, it just made it easier for you to create bottom values ββby accident - types no longer help you. Your language no longer helps you prevent this kind of mistake, and this is bad.
Of course, other lower values ββstill exist: exceptions (e.g. undefined ) or infinite loops. Adding a new possible failure mode to each function β dereferencing null β simply simplifies the recording of alarm programs.