New Utility Functions for the Table Library Like DeepClone and Set

I was thinking recently about how the table object could be even more convenient if it had a few more built-in functions , similar to how table.find is already super useful.

For example, features I’d thought would help :

table.count(tbl, value) — returns how many times a given value appears in a table.
table.set(tbl) — returns a new table with duplicates removed (like a proper set).
table.deepclone(tbl) — deep-copies nested tables to avoid shared references.

I know these can easily be implemented through scripting (and we’ve probably all done that at some point), but having them available natively could make development just a little smoother, especially in larger projects where these operations are frequent.
The @native decorator also helps perfomance, but while it’s a great tool, the reality is that many developers, especially those starting out, don’t prioritize performance or know about these lower-level optimizations.

Having efficient, built-in solutions for common table operations could save time and encourage cleaner, more consistent code across the board, while also getting the benefits from being standardized and optimized at the engine level.

I’m not sure how many implications these additions might have for older places (if any at all), so if there’s anything that could prevent this suggestion from being implemented, please let me know here.

3 Likes

There is something with how luau is designed that I like, not sure if it was intentional or not, but usually, if something is expensive computationally (O(n) or more) the language has less built in features to do that task out of the box. The main exceptions I can think of are table.find, table.sort, and probably some of the string library functions

But then python, instead of using a function, has the in keyword reserved (which acts kind of like table.find()), kind of giving the impression that it’s an inconsequential and basic operation?

The idea is like, you have these abstracted languages, where performance is harder to judge, but having the language designed where easy to compute stuff is easy to write, and harder to compute stuff is harder to write, is elegant to me

Obviously it’s a question of whether the benefits outweigh the consequences

1 Like

table.clone doesn’t deep clone because of several implementation details that need to be addressed, its not just, “dont allow recursive tables”. Should Instances clone? Should script signals be reconnected?

Shallow clone copying references is more obvious, but when you get to deep cloning, every custom userdata has its own implementation detail.

2 Likes

It would be neat if we got a library for array utilities as opposed to general table utilities. There is already weirdness with table.create allocating for the array portion only, not hash. Your idea for table.count/set would probably apply for arrays only. Deepclone is more general, but as mentioned the behavior would be up for question. Personally, I rarely deep clone tables for performance and I usually find it unnecessary. I do always find a deepfreeze utility to be useful often though.

1 Like

If these were to be added, especially to the table library, it would be through an extension of the base Luau language, not as a Roblox specific thing.

Adding stuff to the base Luau language goes through the Luau RFC process not through DevForum feature requests (you could even open an RFC for this yourself if you were so inclined).

1 Like

I didn’t think of that when making my post, but now I see it. Perhaps some kind of deep cloning that follows the same rules of table.clone could work? The term deepclone probably wasn’t the best one to describe what I meant, but if we just extended the current table.clone semantics — keeping the same behavior for Instances, signals, and userdata — while also cloning nested tables, that would already cover most of the practical use cases ( I guess… )

Good idea. As I’ve already replied to metatablecat, deep cloning wasn’t the best term I could’ve used in my example. It was just some quick examples I came up with at the moment when making the post, since there are actually a lot of related aspects that could be considered and potentially added.

Got it, I wasn’t aware of how that works. Thanks for taking the time to explain it. If this post ends up being out of place here, I don’t mind removing it to avoid any confusion.