mid's site

you're logged in as loser

🌍 Go Paperful

🔗 Subscribe via RSS

What's (probably) coming in Lua 5.4

Lua 5.4 is currently in the works, and along with that comes a WIP manual available here. Here I'll be checking out some of the big stuff and showcasing their uses.

Note, this is wobbly information and some info might quickly become outdated.

Local Variable Attributes

New syntax has been added which looks something like this:

local <toclose> fd = io.open("something.txt", "r");
local <const> tau = 6.2831853071;

The identifier that is surrounded by square brackets is called an attribute. The toclose attribute makes sure the __close metamethod of the variable's value is called when it goes out of scope. It's basically RAII like in C++, where objects shouldn't be used outside of where they are defined if using automatic memory management. The second one, const does as you'd expect and prevents the value from changing.

These attributes are hard-coded in the source and are not extensible.

Another bummer is that you can't have multiple attributes for one variable! I don't see why I shouldn't be able to do <const, toclose>.

Userdata supports multiple uservalues

For people working with the Lua API directly, this is quite helpful. As before, if you had to associate multiple Lua values with some userdata, then you had to instead associate a table that referenced said values, causing some overhead. It hasn't become that much more complicated, although this does cause an incompatibility in the API which is patched up with macros.

the_data *data = lua_newuserdatauv(luaState, sizeof(the_data), uvCount);

lua_pushinteger(luaState, 10);
lua_setiuservalue(luaState, -2, 1);


This is still hazy, and there's been debates to do with this feature in the mailing list. Warnings allow the runtime to call a function when there is.. something to warn about? It's pretty self-explanatory. Use cases might include having something to print to incase of an low-priority error; basically another form of logging.

// The embedder.
lua_setwarnf(luaState, on_warn /* The warning function. */, this /* Userdata. */);

-- The embedded.
warn("Coffee levels below 10% of max capacity, refilling recommended.");

The Smaller Changes

  • The numeric for statement's semantics was updated. I rummaged the code for half an hour but couldn't figure out what the semantic differences were exactly.
  • math.random now uses xorshift128+.
  • New %p directive for string.format that returns a pointer to the object.
  • New coroutine.kill function, which aborts it's execution and closes all to-be-closed variables left.
  • New rules for duplicate goto labels.
  • "5" + "5" == 10.0 is now false. Instead, "5" + "5" == 10, and the string's metatable now does the coercion itself, instead of it being a language-level feature.
  • There are more that were even smaller.


There are only discussions so far, and the implementation has this turned off by default. undef would be special syntax to remove a variable from some scope or, in other words, undefine it.

local t = {2, 3, 6, 3, 1};
t[3] = nil;

Currently, assignment to nil is equivalent to removing said key from the table entirely. But with undef, it would instead actually assign the value nil to the key. This way, you can tell the difference between nil or non-existent.


All in all, what do I think? I tried to stay impartial above, but I think we're seeing the slow downfall of another language. We've seen it with Java, and Python; where once there were simplicity and semantic lightweightness now stand language features bolted on and duct-taped together. I wouldn't be surprised if people stayed on 5.3. There were already doubts by other people concerning 5.3 adding unnecessary features.

In my eyes 5.2 is almost perfect, and that's what I will use for a long time.