I didn't go into detail there, John, but it's worth noting that
originally Codd thought that there should be several different NULL
values for relational databases. Later in life, he came to believe
that NULL values (both the single NULL value in SQL databases and
the multiple NULL values in his original relational papers) were
bad.
No, as I remember it, his problem wasn't with NULL, but
rather the DB design.
ie. All instances where you have NotApplicable or NoThing null IN A
DB TABLE can be refactored to a better relational design that didn't
require them.
However, having factored the DB into more tables so neither variety of
NULL occurred, there is still a need for NULL. There is still a need on
occasion to construct reports for user display which are joins of various
tables. And in those "views" there may be some fields are going to be
NULL. And again, it is still necessary to disambiguate between
NotApplicable and NoThing.
Your proposal of multiple types of nil makes life harder. Instead
of:
if foo.nil?
# blah
end
I would have to do:
if foo.nothing? or foo.undefined? or foo.not_applicable?
# blah
end
How about starting with the following in the core
class Object
# This is as is already
def nil?
false
end
def uninitialized?
false
end
def not_applicable?
false
end
def nothing?
false
end
end
class NilClass
# No change here
def nil?
true
end
def to_s
raise "No method, old definition inconsistent."
end
end
class NoThing < NilClass
def nothing?
true
end
def empty?
true
end
def to_s
""
end
def to_i
0
end
end
class NotApplicable < NilClass
def not_applicable?
true
end
end
class Uninitialize < NilClass
def uninitialized?
true
end
end
Now if the rest of the system chose the right version of nil when it
assigned nil to something, the problem would go away and we can extend the
NoThing in a sane harm free fashion.
The problem, as others have stated, is that adding #empty? to
NilClass implies a containment. I'd have as big a problem if we
added #empty? to Fixnum so that 0 returned true and everything else
returned false. (Indeed, would that be correct? Would -3.empty? be
true or false?)
Tut! Tut! I'm having this same problem with my son at school, they teach
him the rote mechanics, but forget to teach the principles. (To be fair, I
only started learning these things when I start reading foundations of
mathematics type books from the university library...)
Come now, what is 3? 3 is 1+1+1. What do we mean by 1+1+1 we mean three
contains a 1 and a 1 and a 1! So if I extract the contents of three I get
1 and 1 and 1 back.
And -3? Surprise surprise it contains three minus ones!
There is a strong overlap between core system design and axiomatic
mathematics.
class FixNum
def empty?
self == 0
end
def length
self
end
def each
if self < 0
# -3 contains three minus ones...
(1..-self).each{|i| yield -1}
else # And 3 contains three ones.
(1..self).each{|i| yield 1}
end
end
end
John Carter Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : (e-mail address removed)
New Zealand
Carter's Clarification of Murphy's Law.
"Things only ever go right so that they may go more spectacularly wrong later."
From this principle, all of life and physics may be deduced.