lua-users home
lua-l archive

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


On 2018-01-28 01:44, Dibyendu Majumdar wrote:
It takes good taste and years of effort to create a language such as Lua. Despite some 'warts' overall Lua 5.3 appears to have reached a state of perfection (or maturity) in my view.

Maturity – yes, definitely.  Perfection - nope, long way to go still.
(That will probably always be true...)  But it's *A LOT* closer to that
than any other (practical) language that I know.

The way it looks to me right now, 5.4 will bring us closer by reducing
temptations to veer off the "Lua way":  The generational GC makes
throwaway structures cheaper, which means you're more likely to use them
and not write "manual" / lower-level code for the sake of "speed".
(Even if it doesn't measurably impact actual speed... most likely, one
never measured anyway. ^,^)

Varargs becoming tables also feels like a step in the right direction,
but I expect that there will be some quirks for the next version to
fix... and that's fine!  5.3 brought sub-types (int/float), which at
least "feel" a bit clunky still...  which is a _good_ thing:  Rough bits
persist if they're not too much of a problem, the team doesn't pick the
first "solution" that comes running along and freezes it in place.  New
things are allowed to stay a little rough & floaty... in time, they fall
into place. [1] (Recall bit library / operators, function environments /
_ENV, tag methods / metamethods, ... (oh right: varargs too ^,^) –
there's no holy cow inside Lua, what must change will change.)

Beside incoming improvements, present Lua also contains lots of tiny
warts... NaN being unusable as a table key is one of the bigger kinks –
a "discontinuity" in the type/value space that's hard to check for and
generates complexity whenever you have to deal with it.  (And no library
ever checks/handles this... because that would be clunky & slow(er), and
so you're stuck writing your own code.) [2]

`__eq` expecting both types _and_ metamethod to match is another one:
By setting a metamethod, I communicate that it can handle values of that
type; by setting the same metamethod/closure on multiple types, I
communicate that it knows how to handle all of these... and yet, Lua
insists that primitive types must match and thereby prevents useful
"duck typing".  (i^2 == -1 is false or (i^2)^0.5 is nan... or maybe
you've written some pretty complex code for a magic workaround.  Same
for mixing tables/userdata and not having to wrap or convert stuff.
This is a deviation from the "mechanism not policies" philosophy that,
irrespective of whether this will or should change, is a surprise / a
discontinuity that results in more complex code, and is therefore not
yet perfect.)

The awesome thing about Lua is that pretty much all the other
"discontinuities" / kinks that I can think of can be fixed _from inside
the language_, often even locally / without affecting other libraries!
(And if I'll run into some other thing that cannot be "configured away"
at runtime, Lua is very hackable!  So it's probably not that much of a
problem.)

-- nobody

[1] To try and make more clear (or confusing ^,^) what I mean here...
From my perspective, it seems the Lua authors seek saddle points, not
local optima.  (Whether intentional or accidental / as a side-effect of
something else, I do not know.)  The big difference is that at saddle
points, movement is cheap, while at local optima, you'd first have to
climb back out to get going.  I think this is a big part of what makes
Lua what it is, and you can see it practically everywhere.

[2] Your(?) idea from a while back of making NaN false doesn't fix this
– it adds another kink that permits a simple approximate test but...
well, suddenly, not all numbers are `true` and you have one other
discontinuity to worry about.  The best thing that I could think of, so
far, is to have special case logic for the float paths in the table
code, possibly substituting a single "canonical" NaN (recall that
there's billions of them... =/) for use as a key.  Last time I patched
this (...5.2? 5.3.1/2? In 5.3.3/4(?) some table code changed, so it
broke...) I was able to hide most of the code on error paths / behind
checks that already existed.  But people always worry about speed... so
let's just see what happens.