At 02:39 AM 9/21/00 -0700, Glenn Linderman wrote:
>Thanks, Paris, for your intervention, although I fear it was too late.
>
>Well, since Tom claims to have put me in his kill file, he may never see
>this. But for the record...
>
>Tom Christiansen wrote:
>
> > >Can't we all just play nice?
> >
> > Apparently not. Several of us attempted to explain why this didn't
> > make sense, for many reasons. GL wouldn't hear any of it, stubbornly
> > adhering to this notion despite what was said, often completely
> > ignoring or apparently purposefully misunderstanding the points.
>
>It's true that I think that NULL would be an extremely useful concept,
>and until there is a cogent argument to the contrary, I will continue to
>believe it. I've been working with databases for 21 years, and with Perl
>for 5, and I truly believe NULL would be a useful addition to using Perl
>to work with databases.
Ok, let's see if I can make some sense of this...
You want a singleton scalar datatype in addition to the exising scalar
datatypes of strings, numbers, references, filehandles, and undef that
represents an unknown value, similar in semantics to the SQL notion of "NULL".
I'm going to call this prototypical datatype/value "unknown", in order to
represent its meaning in a more perlish way, as well as to avoid the
overloaded semantics of NULL (and it's related near-homonyms: SQL's unknown
NULL, C's NULL invalid pointer, Lisp's NIL, ASCII's NUL, the null string,
the null list, etc). Calling anything NULL these days is likely to be
confusing, so I'll avoid it.
This doesn't matter as far as database work goes because DBI can convert
between SQL NULL and perl unknown just as easily as it can convert between
SQL NULL and perl undef.
I just reread RFC 263, and I do have some unanswered questions. How
pervasive is this "unknown" value? If $a is unknown, what about $a
Given:
$a = unknown;
print "\$a is ", ($a ? "true" : "false"), "\n";
What should print?
I think the example of:
die "Fatal, \$name is unset!" if ($name == null);
is flawed. It will never die, because as you said, two unknown values
won't compare as equal. Besides, the test would try to convert both $name
and null to numbers before doing the numerical comparison, so it would
depend on what the numerical value of unknown is. You really need a
"known()" built-in to go with this, such that known($a) is true if $a is
NOT unknown.
What gets me is that the implementation of this would require virtually
every operator, function, etc in core perl to be special-cased to deal with
the unknown value, yet the RFC makes no mention of this.
With undef, it's simply a matter of having the internal representation of
undef return 0 or "" when asked for a numerical or string value. This
makes most things deal with undef nicely -- even booleans. With unknown,
since it is specifically designed to propagate, everything would have to
deal with unknown values, not just integers, or strings, or booleans.
Importantly, unless you decide something arbitrary like "unknown is false"
like the way that it was decided that "undef is false", then you throw out
the law of excluded middle (every expression is either true or false), and
make things like the ?:, ||, or && operators go all wiggly (not to mention
if, while, unless, and so forth). And if you do arbitrarily say "unknown
is false", how do you deal with the cases where you want to say "I don't
know if it's true or false"?
SQL gets away with this by saying that boolean contexts require a boolean
value, which you get by using a relational operator. People don't go "IF
variable THEN..." unless they know that variable will be boolean -- and
can't be NULL. And they then decided that using a relational operator on
NULL will always yield FALSE. That works for them.
But that's not Perl. Perl programmers like functions that return a useful
but true value on success, or undef on failure, and are quite comfortable
going:
$var = f();
if ($var) { g($var) }; # f was a success
That won't work if $var can end up being unknown. Worse, fixing it by saying
if (defined($var)) { g($var) };
doesn't help, because the RFC says that defined(unknown) is unknown!
Your unknown seems to be very special-case for doing SQL-based DB work. In
all my time programming it, I can't remember wanting it. It doesn't seem
to integrate with the rest of Perl all that well, requiring massive changes
under the hood to integrate it and the potential for messing up lots of
long-standing Perl idioms, for a relatively small benefit.
Damian mentioned that his Q::S package and RFC would/could provide
something with similar semantics, and his RFC would also likely result in
massive changes under the hood, but it also provides a large generally
useful functionality (and in CONSTANT TIME, too ;-). It is unclear as of
yet if the benefit of Q::S will outweigh the probably cost of Q::S. Can
you make as strong a case for unknown?