lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> I thought I had to use your new operators both when I put nil into a
> table AND when I try and take it out.

That depends on what you are going to do with the results, I suppose. Let
me be clear: I'm not saying you have to use the new operators at all. I'm
not suggesting that boolean values be changed in any way. I'm suggesting
that nil continue to be the (unique) false value. So existing boolean
expressions need not be changed at all, and neither does putting boolean
values in a table unless you find it annoying that the false value is
indistinguishable from a non-existent key, and you don't like workarounds
like:

> I already have that.. it's called:

> table.a = 0
> if table.a ~= 0 then
>  print "true"
> else
>   print "false"
> end

I agree, and that's why I don't think false is necessary. However, the
world is not always that simple, as various people have pointed out.
Sometimes you need to put a value in the table without knowing whether it's
a boolean or not. 99.9% of the time that is not the case, which is why I
said that 99.9% of the time you don't need the operators. It might be the
case, for example, when you're trying to memoise the results of a function
which might return nil, as John McKenna argues.

When it is the case, you could do it the same way as you have done:

do
  local pseudonil = {}

  function put(table, k, v)
    table[k] = v or %pseudonil
  end

  function get(table, k)
    return table[k] ~= %pseudonil and table[k]
  end
end

You can then put that into the appropriate tag methods for the table.

I suggested that last week, and got jumped on for "having to think up a new
workaround every time" and "having a false value that was true". I suppose
it is kind of a pain to write new tag methods all the time, although I
would have thought that you could just do it once.

So what to do? I find the addition of "false" to the language a bit
annoying because it changes the semantics of
  a = a or default
which is an idiom I use a lot, and because it doesn't strike me as either
clean or elegant. However, there are those who are really stuck on having
both "false" and "nil". Adding false to the language changes the way
existing code works, whether or not you use false.

I was suggesting an alternative to that, which as I said, would be
invisible 99.9% of the time and easy to use the other 0.1% of the time, and
which had no impact on (my) existing code. However, I noted that it solved
a couple of existing problems as well: the idiom
  a and b or c
is frequently used by Lua programmers (as the C-operator a?b:c) but if
fails precisely in the case where b is nil. In addition, as Roberto pointed
out:

> The 'or' operator never worked for boolean values. If nil (the false
value
> in 4.0) were among the valid values of "a", the expression "a or b" would
> not give you the first "valid" (or defined) result.

> The boolean type did not change that. (At least now we can speculate
about
> a "ond" operator ;-)

"ond" strikes me as a bit special-purpose, too. So I'm speculating. Having
a "true false" value (instead of two false values) does let you write:

  a and !b or c

when you mean a?b:c, and it lets you write

  a or b or c or d

when you mean "the first one of a, b, c, d which is defined" and

  ?a or ?b or ?c or ?d

when you mean "the first one of a, b, c, d which is true"

These are certainly different tests, at least in a world in which undefined
and false are differentiated.

Arguably, this is backwards. However, there is a lot of code written for
Lua which assumes the first will do what it does (check definedness) and so
we can say that boolean types are the addition to the language, so we have
to mark them.

Personally, and I speak only for 90% of the programmers who inhabit my
skin, I find the ? and ! operators more elegant than a collection of "ond"
"andef" "\\" etc operators. But if someone came up with better punctuation
than !, I would be equally happy.

I also note in passing that either one of these operators, which are by and
large identity operators, would also allow the removal of the syntactic
ambiguity introduced in Lua 4.1 to allow expr(exprlist) as a function call.
(i.e. you can write (f or g)(42) now, but that may mean that you need a
semi-colon to end the previous statement.) With a prefix identity operator,
you can reasonably insist that the expr start with an id or a uniquely
prefix operator, since !(f or g)(42) certainly means the same thing as
(f or g)(42), and takes virtually no time to compute, but does not require
the semi-colon at the end of the previous line.

R.