I'm not familiar with the language you are writing in (being primarily a C programmer), but I gather the a variable of type "List<T>" is allowed to refer to either an object of type "ListNil<T>" or an object of type "ListCons<T>". "ListNil<T>" fills exactly the same role a "NULL" so what you have created is exactly a NULLable pointer, only with a different name and more complex syntax.
A rose by any other name still has thorns, and a NULL de-reference by any other name still causes a run-time-exception or worse.
All values are "created out of thin air". They are abstractions which we create and use to try to model "real" things. Values that are useful we re-use. Values that are not, we forget. NULL turns out to be useful.
Your argument against NULL would seem to apply equally to the value '0'. It is an arbitrary magical value - that the Romans seemed to manage with out. It is a value of every (numerical) type, yet it doesn't support being the divisor in a division. We really should eradicate it - that would get rid of all divide-by-zero errors forever.
Of course, divide-by-zero errors are not caused by the availability of a 0 value, but by the misuse of that value. Similarly NULL pointer de-reference errors are not caused by the availability of a 'NULL' value, but by the misuse of that value.
Posted Apr 1, 2011 4:39 UTC (Fri) by HelloWorld (guest, #56129)
[Link]
> I'm not familiar with the language you are writing in
It's Java (though I don't usually use that language).
> "ListNil<T>" fills exactly the same role a "NULL" so what you have created is exactly a NULLable pointer, only with a different name and more complex syntax.
No, it's not the same thing. As was pointed out multiple times by now, null references can show up everywhere, even in places where they don't make sense and where nobody ever intended or expected them to do. On the other hand, ListNil<T> objects are allowed only allowed where lists are allowed, and any sensible program that operates on lists expects those lists to end at some point (in eager languages at least).
> Your argument against NULL would seem to apply equally to the value '0'.
No, 0 isn't something that somebody just made up. If you don't have 0, you can't add two integers as the only sensible result of adding x and -x is 0. So yes, the fact that you can't divide by 0 is a problem, but getting rid of that is hard. No such argument can be made for null.
I also dislike the fact that null mixes up many different concepts that ought to be separate. null was used to represent optional values, empty lists, empty trees and probably all kinds of other things which don't have anything in common.
RE: nullable pointers
Posted Apr 1, 2011 6:06 UTC (Fri) by paulj (subscriber, #341)
[Link]
Sure, but you still have a specialised nil type. Whether you use a null reference on a List type to denote the end of the list or a special EmptyList class, it still means your code has to take to check what exactly the reference is pointing to before going through it to avoid a runtime exception.
I don't see how getting a ClassCastException is any better than a NullPointerException. Even though you've created a new type, neither you nor the compiler is any better position...
RE: nullable pointers
Posted Apr 1, 2011 8:22 UTC (Fri) by nybble41 (subscriber, #55106)
[Link]
The example was simply to show that you don't need all pointers to be nullable to have linked lists. The advantages for this case are minimal, since linked lists specifically depend on the 'next' pointer being nullable. However, linked lists are a hardly representative of pointers in general, particularly in a language like Java where all objects are accessed via pointers. The benefit of making pointers non-nullable by default is in the majority of cases where nulls are nothing but a source of runtime exceptions.
The advantages tend to be more pronounced in languages like Haskell, however, which have more advanced type systems which handle this sort of subtyping without any need for runtime casts. As you point out, in Java you would need to explicitly cast from List<T> to ListNil<T> or ListCons<T>, an operation which can fail in much the same manner as dereferencing a null pointer.
RE: nullable pointers
Posted Apr 1, 2011 13:33 UTC (Fri) by HelloWorld (guest, #56129)
[Link]
> Sure, but you still have a specialised nil type. Whether you use a null reference on a List type to denote the end of the list or a special EmptyList class, it still means your code has to take to check what exactly the reference is pointing to before going through it to avoid a runtime exception.
How many times do you want me to repeat this? The fact that you need a way to represent the empty list does not mean that you need nullable pointers _everywhere_, even where they _don't_ have any purpose (unlike the list case).
RE: nullable pointers
Posted Apr 1, 2011 14:25 UTC (Fri) by paulj (subscriber, #341)
[Link]
That isn't what you were arguing earlier though. You have been arguing that nullable types are *always* a bad thing (in a grandparent to this post) and there is *never* a need for them (to paraphrase several other comments of yours).
To my mind, having to go from checking the value of a reference to checking other properties of a composite object (the type, or a length attribute), and still being left open to runtime-exceptions (with a different name) if you forget, means you still are facing fundamentally the same problem.
Can the compiler maybe catch a couple more problems it wouldn't otherwise. Sure. Is it a silver bullet? Sadly, still no.