As a Roblox developer, it is currently too hard to do default assignments in a performant but also compact way.
If Roblox is able to address this issue, it would improve my development experience because it would allow for me to condense enormous sections of code into something much more readable.
With luau a few new shortcuts were added for doing operators and assignments (+=, -=, /=, *=, etc). This greatly reduces the size of some code and makes it way easier to type out some things.
One thing which is used everywhere, maybe just as commonly is default assignments. When the existing value is nil it gets assigned something, but, after that it isn’t assigned anything new.
This is the most performant way I know of to do this:
local value = current
if value == nil then
value = default
current = value
end
The problem with this, however, is, it takes up 5 whole lines and is difficult to type even with autocompletion and excessive use of copy pasting. It has very bad readability too, and, I think its a confusing piece of code to look at compared to most things, but, its used almost everywhere on Roblox.
If this got its own assignment operator not only could this likely be used to improve performance by not having to allocate extra locals and do extra assignments, this would greatly improve the readability and size of code and would greatly speed up my development process.
I usually use this simple structure at least two or three times in most scripts and sometimes even more due to how useful it is but that ends up contributing a lot to how much I am typing and it happens to be one of the slowest structures for me to type out since most of it can’t be auto completed and it isn’t repetitive.
Here is an example snippet from some code I was recently working on:
local services = {}
function Linker:GetService(name)
local serviceModule = ClientServices:FindFirstChild(name)
if not serviceModule then
error("Invalid service '"..name.."'", 2)
end
local service = services[serviceModule]
if not service then
service = require(serviceModule)
services[serviceModule] = service
end
return service
end
I use this sort of thing in my frameworks all of the time and it always feels like bloat to me
Having a way to do some sort of “default assignment” would fix a lot of my issues and make this much more clear as well as potentially allowing for extra performance benefits by reducing assignments even more.
Additionally, being able to return and assign at the same time would save an extra value access and condense the code more.
I know syntax proposal is an iffy thing, but, as an example if the above code could become this it would greatly save space and could allow for extra performance benefits:
local services = {}
function Linker:GetService(name)
local serviceModule = ClientServices:FindFirstChild(name)
if not serviceModule then
error("Invalid service '"..name.."'", 2)
end
return services[serviceModule] := require(serviceModule)
end
This wouldn’t need to mean assignments can act as expressions which introduces a lot of problems, instead it could be its own syntax that can happen exclusively after a return, kind of similar to how you might look at a repeat until
loop where you can have an expression after but in this case its any statement, function call, assignment, etc.
return a, b, c, _, _ = 1, 2, 3, 4, 5
could be valid for example and would assign a
, b
, and c
to the corresponding values and then return all 5 values in order which would allow for returning any shape you currently can by using _
s as a placeholder like for loops already do.