On 7/26/07, Keith Hodges keith_hodges@yahoo.co.uk wrote:
As for flakiness, a generic message eating null, that does its job could be less flaky than maintianing specific null-objects for different domain models.
The problem with message-eating null is that it will happily do *more* than its job. This is what I find objectionable. If you are somewhat familiar with Haskell, a message-eating null is very much like the Maybe monad. But unlike Haskell, without a type system to contain it all object references throughout the system effectively become maybe-values, and all implicit continuation calls turn into bind operators.
In other words this means that a null accidentally leaking outside the area where it was expected can silently cause some actions to not happen. What you deal with in that case is not just a null of an unknown origin that Nevin focused on in his write-up, but things breaking because some code didn't run in the past because of a stray null value. When we write ifTrue:ifFalse:, we expect that each time it runs one of the branches is taken. In a system with message-eating null, this is no longer an invariant.
Perhaps we disagree on what constitutes flaky. Flaky in my book is poor locality of failures with respect to their causes. If I open a door and a window falls out, that's flaky. So is if I change a method and things stop working in an entirely different place because a null value leaked, ended up as the receiver of ifTrue:ifFalse: and disabled both execution branches. Indeed, maintaining specialized null objects is more work (however, more often than not they are part of a hierarchy of classes whose protocols you have to coordinate anyway), but that work in the end produces a program that is more predictable and is more likely to break where it's broken. I value that in my programs.
Cheers,
--Vassili