Release Notes for 394

What is the difference bewteen table.unpack and the global variable unpack? Will the global variable unpack be deprecated in favour of table.unpack, or is the latter preferred over the former?

4 Likes

There is no difference; Lua 5.2 removes global unpack but we obviously can’t do that so both will continue to function.

7 Likes

Will only one be optimized because you want to make it the idiom?

We currently don’t plan to heavily optimize either; I expect that if we do, we’ll treat them equally. The real point of this update is table.pack, and table.unpack went along for the ride.

3 Likes

So as a general rule, we should treat the global as deprecated?

1 Like

I’m curious about table.pack. Doesn’t that just make an array from the arguments with a field n indicating length? How is it useful?

1 Like

It’s useful in cases where you want to marshal the function argument calls across a network boundary as a table, or just store them for later.

You can use {...}, but the problem is that if you have any nil arguments in the function, the size of this table will be hard to compute (because of the quirks of # when dealing with arrays-with-holes).

You can compute the size using select('#', ...) yourself of course. But that’s pretty obscure.

Instead you can use table.pack as a convenience method that’s also going to be slightly faster.

13 Likes
Added Function void MarketplaceService:SignalPromptBundlePurchaseFinished(Instance player, int64 bundleId, bool success) {RobloxScriptSecurity}
...
Added Event MarketplaceService.PromptBundlePurchaseFinished(Instance player, int64 bundleId, bool wasPurchased) {RobloxScriptSecurity}
...

Question: Will you purchase Rthro bundles, non-Rthro bundles, or both using this?

The API for purchasing bundles should be unlocked eventually, I hope.

4 Likes

“Mixed” tables with string keys or nil array spaces can’t be marshalled/replicated last I checked?

I would consider table.pack’s result pretty obscure, as an “n” field isn’t used anywhere else in the API. unpack also doesn’t check for “n” (thankfully), so one would need to write table.unpack(t, 1, t.n) to get this to work, which is obscure in its own way.

This is not true if a custom packing function is optimized to not create a table in the case where the tuple length is 1 and isn’t already a table (creating a table is a whole lot slower than a type check). Storing the length at the beginning of the array as {select("#", ...), ...} would also use a bit less memory than using the hash part of the array (assuming the table doesn’t need to be reallocated to the nearest 2^n in the case of a trailing tuple.)

I love seeing improvements to the Lua API and I’m sure table.pack is convenient for a handful of devs, but it’s pretty obscure even though it’s in vanilla Lua.

1 Like

This is talking about manual implementations, not builtin - builtin mechanisms indeed don’t support mixed tables.

You’re making a lot of assumptions that may or may not be correct. Storing the length at the beginning of the array is a bit of a hack, and allocating the table the way you suggest still results in two allocations because the size isn’t known up front (so you create the table with 1 element and then grow it to the final size).

The .n in table.unpack fwiw is - as far as I know - a homage to the original Lua behavior that was deprecated in 5.1 where .n could store the array length. But .n is clearly documented in table.pack semantics, whereas select trick is something you have to learn… somehow… by reading the entire Lua reference manual I guess?

Anyway, if you don’t like table.pack - don’t use it. But it’s a builtin function in Lua 5.2 and it complements unpack reasonably well. Our general goal is that if there are features in later versions of Lua that are useful to the community, and are easy for us to pull in - we will do so. At this point we’ve added most of the 5.2+ library functionality (utf8 and bit32 included), and these just complete the set.

4 Likes

Okay that’s fair. I think I’m just eager to see a non-standard method like table.find implemented, as it would greatly improve my game’s performance in many cases.

Pack is useful with var ret because you cannot do
local …=f()

So you have to do one thing with the var ret, either:
local t={f()}—but table size is incorrect because of nil values
Or
local n=select(‘#’,f())—but then you miss the args

So what I’ve been doing until table.pack becomes available is implementing my own pack to let me get the size and ret:
local t=pack(f())
local n=t.n

Edit: not sure if I should have replied to you

1 Like

Does that mean you’re open to adding other 5.2+ things, like string.pack or hex/unicode string escapes? I believe those are basically all that are missing that aren’t fundamental changes to the language.

Please file feature requests for this and we can take a look. On string.pack specifically I looked at this briefly and wasn’t sure if we should take it as is - there are parts of this API for example that behave differently on 32-bit vs 64-bit systems which isn’t ideal. But if there’s a need for this we can figure out if we need to adapt this to get more consistent behavior.

Looked at string.pack again and we’ll need to think about it. It seems super useful, but we’d need to substantially alter the spec to make all platform-dependent formats they have there fixed-size, and apparently that’s like half of the formats. :-/ As a result our version will very likely be incompatible with native version in terms of produced data. Might still be useful but not sure.

Even with those changes it would probably still be useful, though I’m not sure how much effort it would take to implement those changes and to document them.

I think adding string.pack or any kind of packer right now is jumping the gun. My concern is that the Roblox API doesn’t play nice with binary strings in general. With few exceptions (like JSONEncode/Decode), passing a Lua string through the API leads to truncated null characters. DataStores, which encode in JSON, significantly inflate the length of non-ASCII bytes. Until this poor support for binary data is addressed, the usefulness of string.pack or any such function is greatly reduced.

1 Like

Yeah I agree we need to improve binary data support across the board. I suspect in the future pack/unpack will be useful but I agree, it’s probably premature. They are also from Lua 5.3, we can wait until Lua 5.4 to see if they stay in tact or get deprecated or …

6 Likes

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.