lua-users home
lua-l archive

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


2018-06-05 10:03 GMT+02:00 Viacheslav Usov <via.usov@gmail.com>:
> On Tue, Jun 5, 2018 at 3:35 AM, dyngeccetor8 <dyngeccetor8@disroot.org>
> wrote:
>
>> Current behavior of "and" and "or" operators is equivalent to following
>> Lua-like functions.
>
> The behaviour is documented in section 3.4.5, and the essential part of it
> is the "short-circuit evaluation; that is, the second operand is evaluated
> only if necessary". Your explanation is far more complicated than that and
> is technically incomplete and/or inconsistent anyway.

The OP was playing an intellectual game (as is clear from his remark
"I should add that I do understand what's happening here.") The rest
of us don't want to play along, and would rather discuss the
curiosities of 'and' and 'or'. So (sorry, Sam) do I.

So with the thread well and truly hijacked, here is my 2¢'s worth.

I always find the distinction between true and `true` difficult to
make when writing documentation. It might show up only as a different
font. So I say "tests true" rather than "is true", and "a true value"
rather than "true".

The difficulty arises because 'boolean' is a late addition to Lua,
forcing a change in the semantics of 'and'/'or' so that the words can
be used as if they are boolean operators.

The and/or evaluation directives were already in Lua1.0, and simply
meant "do (or don't) do something depending on whether a certain value
is nil". Comparisons were not part of the picture. They did not result
in first-class values, you could only use them in conditional
statements,

When we get to Lua 3.0 (didn't test 2.x)  comparisons evaluate to 1 or
nil, which when seen as true or false and combined with and/or, behave
in the way you expect, so we don't need any new keywords or types.

Which is basically when the issue of nils in tables started. You are
memoizing a lot of expensive function evaluations, the result of each
of which is just a true/false value, and you can't distinguish between
a case already found false and a case not yet treated.

So they said: we don't want to allow nils in tables. We'll rather
create a whole new type so that you can store `false` instead.

Now we enter the modern era (Lua 5.0) From the point of view of
'and'/'or', nil and `false` both behave like nil did.  Not because it
is sensible from the point of view of evaluation directives (it isn't)
but because it has to be that way for boolean algebra to remain valid.
So 'and'/'or' is not really overloaded, but their semantics has
changed to accomodate the new datatype. You cannot longer blithely use
the idiom "x or default" when "false" is a reasonable value for x to
have.

As the OP has pointed out, the position of nil has become anomalous.
But this not because nil is special, it is because the class of values
that test false has another member besides `false`.

Now nils in tables is again on the table. They said: we don't want to
offer you a new value that behaves like nil except that the key/value
pair remains in the table when the value is nil. Instead, you can
compile with an option that always behaves that way. Except that
tbl[k]=nil will still mean that the key is removed.

Some of us noticed that in the code, though, such a new value is in
fact introduced. When we tried explaining in terms of the
implementation what happens, they were annoyed. Not helpful at all,
they said.

But the notion had other drawbacks, so nils-in-tables has been
scrapped. For now.

Watch this space.