|
From: Fredderic U. <mag...@gm...> - 2008-06-15 10:03:32
|
On 14/06/2008, Alexandre Ferrieux <ale...@gm...> wrote:
> On 6/14/08, Andreas Leitgeb <av...@lo...> wrote:
>> Alexandre Ferrieux <ale...@gm...> wrote:
>>> Here are the figures below. I've done a 3-way comparison:
>>> (1) list of integers
>>> (2) list of Cons-based (Maybe Int)
>>> (3) list of List-based (Maybe Int)
There are only two kinds of NULL... Those that are, and those that
aren't. But I'll get to that latter.
The primary purpose of NULL, as most of us know it, is to mark
something as missing. NULL isn't supposed to be a value. It's main
use is not even as an empty value, but as an absence of value
distinguishable even when ANY value is permitted (including the empty
string).
The most common implementation of a true NULL in todays TCL, is the
unset variable. I'm pretty sure we ALL use [info exists] from time to
time. That's a very real form of NULL, so arguing that NULLs are evil
is about as logical as making [info exists] always return 1, and
auto-initialise all variables in all uses. After all, who ever heard
of incrementing a NULL, anyhow? There's only one type of unset
variable, and that's the unset one. It's distinguishable from EVERY
other type of element, even the empty one. But it's also limited.
You can't put an unset variable into a [list]. It needs to be encoded
in some manner to "represent" an unset variable. Trouble is that most
manners of encoding NULL require extra checking. You just have to
look at the arguments against using a real NULL C pointer to represent
NULL internal to TCL, to see why that's a bad idea. The first
argument that crops up every time, is "but you'd need to check for it
everywhere" (which translates roughly to "that sounds like too much
hard work for us"). Mind you, I'm not saying that's an invalid
argument, but then in the same breath those same people all say, "but
it's okay if YOU do twice as much work to somehow wrap any value that
MIGHT be null in an ad-hoc per-instance and vastly more wasteful
method, and then have to unwrap it any time you want to use it". That
sounds just a little, how shall I put it, hypocritical? Again,
though, I'm not saying that IS the right thing to do. Just that that
particular argument is crap.
And there again. What is a C NULL anyway...? Interestingly, it's a
regular value, just like any other value. It's nothing more than the
number 0. It could have just as easily been 1 or 3. What makes this
one special, is that it's linked to a very specific concept. The
concept of a piece of physical silicone that we agree not to be used
for any other purpose. (In actual fact, even that's not entirely
true, it's usually a jump instruction, or an exception vector, or
something along those lines, and don't even start on what happens with
memory mapping in the mix.) You get to know this fact a little better
when you're using some small embedded processors with freakish
addressing.
How do the [cons] or [list] based methods achieve this? By using some
value that they hope no one else will use. But what to do if some
piece of script comes along and wants to return a string that just
happens to look like the string rep of your [cons] and [list] methods.
All of a sudden you're back to square one. It has to wrap its
output, and you have to unwrap it again when you get it. They're
still no different than the "pick a value" method suggested by
everyone else, it's merely an optimisation, and you may as well be
sticking an extra "control" character in front of the string rep of
what you're returning.
That's why I suggested an === operator, or an [info isexactly]
command, and I wasn't alone in this interpretation of NULL. It allows
you to get back to the original concept of a particular piece of
physical silicone that we all agree won't be used for anything else.
Nothing can return NULLs blindly, or accidentally, because nothing but
the current interpreter can recognise it as a NULL (sharing a single
NULL among child interpreters, maybe even threads, might well be
possible). The NULL should be empty strings, or perhaps a \0. Heck,
add an [info null] command to return it, and allow it to take an
optional argument that assigns a new value to be used to represent
NULL (it would have the extra benefit of ALWAYS doing an in-place
assignment so as to keep all existing NULLs valid). Then anyone who
feels that \uffff is a good NULL indicator within their application,
can use that too.
While we're on the subject, just try serialising NULLs in C, you'll
have exactly the same problem as in TCL. You can't print the value of
a NULL, or store it in a string (the NULL pointer value, as opposed to
the NUL character value). In C, attempting to do that is usually
indicated by either a segfault, or a busfault (both of which are
generally considered very bad). In TCL, though, we want to be a
little nicer than that.
The === or [info isexactly] features, together with a ::tcl::NULL (the
C API is, if I recall correctly, quite capable of protecting its
special semantics. Even in TCL you can use a [trace] to make it
effectively read-only) or [info null] command, allow you to not only
do this, but also add new application-specific NULLs (which someone
mentioned), and whatever else. In effect any value can become a
singularity, indistinguishable from any other.
The ONLY real requirement of any definition of a NULL that I've seen
throughout this discussion, is that it be outside of its domain (it
must be distinguishable even from another item with an identical
representation), which we refer to as NULL. [cons] and [list] simply
don't provide that in a general context. The {}{} (and similar)
notations provide this, however, by way of a parsing exception,
allowing a specific internal value to be put in its place. {}{} is
just another form of $::tcl::NULL or [info null], and so forth.
But, once you convert them to a string, EVERY method of NULL
representation yet discussed, wihout fail, has the exact same problem
facing the [list] and [cons] methods. They're no longer distinctive.
So unless you're offering something different, like the original
NULL-is-not-quite-EIAS suggestions, it's all pretty much pointless.
Personally, I'd like to see === or [info isexactly] or some such,
because it facilitates the construction of a true NULL, but also
bestows a few other limited benefits.
Fredderic
|