Closed rimuy closed 2 years ago
The proposed spread syntax is ambiguous: {...-t1,...-t2}
could be interpreted as merging the results of -t1
and -t2
, or it could be interpreted as doing subtraction with the first variable argument and t1 and t2. Currently it is interpreted as doing subtraction.
Would {...{1},...{2}}
be {2}
, {1}
, or {1,2}
?
{2}
and {1}
makes sense if it is just mapping keys into the table (the order of assignments is undefined).
{1,2}
makes sense if it doing array concatenation.
I believe that having functions do these tasks is better than having a built in syntax.
You mentioned unpack
, but that isn't a good function to use for copying arrays. {table.unpack(t)}
will work fine if t
is small, but if it is too large then it'll error.
You said that want support destructuring the same way Typescript does, but in the examples you use =
for property renaming while Typescript uses =
for default value.
local k = 1
local {x=k} = {} -- declare x as 1 or declare another k with nil?
local c = 2
local {x=v=c} = {} -- declare v with 2, confusing
This issue by itself isn't actionable so I'm going to close this.
Both features would require an RFC to be considered. OTOH spread is unlikely to be accepted at this point in time because it's difficult to remove implicit spread in tail position so explicit spread makes the spread story "fragmented", and there's some implementation challenges - an ideal proposal for spread would come up with some idea of how to move away from implicit spread... unsure how.
Destructuring is much more straightforward (don't treat this as a promise that we'll get that feature...). I think Quenty had plans to submit an RFC for that.
Concept
Recently the language has gained support to if-then-else expressions, which shortened the way we deal with conditional values, rather than using if statements. On that note, I'd like to suggest adding support to tables destructuring and spread the same way typescript does with objects.
That way it would not only bring a key into the scope without needing to create a variable for the table and for every key we want to use, but also make our code a lot smaller. Of course, in Luau's case, that would only apply to string indexes, since we can make a tuple via
table.unpack
and reference the returned values likewise.Examples
Merging dictionaries
Currently there is not way to destructure string indexed values in a table, and we cannot call unpack to do so, since that's used for number indexed values to return tuples, like said before. If we wanted to do so, we would need to create an utility function for that case. (e.g.
merge
,assign
)To resolve that problem, we could use
...
as the spread operator, just like we do when handling varargs, but instead placing it before a table reference, inside a table.For example, here we want to create a new table that contains all the keys from
t1
andt2
:Current
With spread
For the record, we could also do the same above without variables:
Referencing Keys
Let's say we have the functions
foo
andbar
. Both takes as a parameter a destructured table.foo
prints the result of the sum ofx
andy
.bar
prints the result ofx * y * z
, butx
is the only key that is being directly referenced.Current
With destructuring
Using spread inside a table that is already being destructured, creates a new table that contains all the keys that were not referenced like
x
.Nested Tables
Key Assignment
In addition, it would also be nice to assign the reference of a key to a new one:
This would be a great alternative to creating variables for aliases when working with libraries that returns a dictionary (e.g. roact):