What is the difference between undefined in Haskell and null in Java?

Both are terms whose type is the intersection of all types (uninhabited). Both can be passed in code without glitches until you try to evaluate them. The only difference that I see is that in Java there is a loophole that allows null evaluations for a single operation, which is a comparative equality comparison ( == ), whereas in Haskell, undefined cannot be evaluated at all without throwing an exception. Is that the only difference?

Edit

What I'm really trying to solve with this question is why in Java was such a null such an obviously bad solution, and how does Haskell avoid it? It seems to me that the real problem is that you can do something useful with null , namely, you can check it for nullness. Since you are allowed to do this, it has become the standard agreement to bypass the null values ​​in the code and indicate to them "no result" instead of "there is a logical error in this program." Whereas in Haskell there is no way to check whether the term evaluates the bottom without evaluating it and exploding the program, so it can never be used in such a way as to indicate "no result." Instead, one is forced to use something like Maybe .

Sorry if it seems to me that I play quickly and freely with the term "evaluate" ... I try to draw an analogy here and accidentally formulate it. I suggest that the sign that the analogy is inaccurate.

+48
java null types haskell maybe
Oct 18 '10 at 20:05
source share
2 answers

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.

+69
Oct 18 '10 at 21:15
source share

Your description is not entirely correct. You say that null impossible to evaluate. However, since java is an impatient language, this means that f(null) will invoke NPE no matter what the definition of f (since method arguments are always evaluated before the method runs).

The only reason you can bypass undefined in haskell without getting an exception is that haskell is lazy and does not evaluate arguments if it is not needed.

Another difference between undefined and null is that undefined is a simple value defined in the standard library. If it was not defined in the standard library, you could define it yourself (for example, by writing myUndefined = error "My Undefined ).

Java null has a keyword. If the null keyword was not there, you would not be able to define it (executing the equivalent of the haskell definition, i.e. Object myNull = throw(new Exception()) , will not work, because the expression will be evaluated exactly there).

+7
Oct 18 '10 at 20:13
source share



All Articles