[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Has Lua reached perfection?
- From: nobody <nobody+lua-list@...>
- Date: Mon, 29 Jan 2018 02:55:55 +0100
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.