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 pointer from changing.

These attributes are hard-coded in the source and are not extensible, which is a bit of a bummer.

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);

Warnings

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 where the difference was 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.

undef

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.

Conclusion

All in all, what do I think? I tried to stay impartial above (and failed), 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.