Luau Recap: August 2020

I don’t know if here is the correct place to make a Luau feature request.
Anyway, it would be great if I could create a sub-operation inside an if, like C++.
Ex:

if (i = 1+1) == 2 then -- puts the result of 1+1 inside `i` and compare if i == 2

In Lua assignments are statements, not expressions, and this can cause unintended behavior like someone forgetting to add an extra = when they intended to compare i to 1 + 1 but not assign i to 1 + 1 and check if 2 is truthy.

That is not happening.

The fact that you can do that in C is widely regarded as a mistake, as it creates countless bugs where developers accidentally type if (a = b) instead of the if (a == b) they actually meant.

Any plans for string literal types?

Y’all do type checking on the arguments for Instance.new, for example. It would be cool if we could also have access to that ability. I suppose it is less useful in Luau than in TypeScript, though.

3 Likes

It would be great if I could to create an “alias” variable to change a value for a long dictionary sentence, ie, to change a value by reference, as currently can be used in c or c++ (C++ References).

For example, currently if I have to change a value of one element of this complex dictionary…

CellAux[Key][4][Materials[Material].Output].LastMaterial = Material

… and in every point of the program I need to change it, I have to repeat this long sentence every time.
But if I could do something like c++, like:

local &LastMat = CellAux[Key][4][Materials[Material].Output].LastMaterial
LastMat = Material -- will actually change the value of "CellAux[Key][4][Materials[Material].Output].LastMaterial"

This would improve a lot the code readability.

That could be nice, but there are two issues. For one, your game/code structure could and should probably be changed to avoid that kind of messy assignment. For two, functions exist. You can just define a function to do that for you. On another note, this would be great for cases where neither of those apply.

You can already get most of the way there and get almost the same readability though:

local LastTb = CellAux[Key][4][Materials[Material].Output]
LastTb.Material = foobar(LastTb.Material)
1 Like

BrickColor.Random is missing:

image

Try lowercase r (BrickColor.random()). Roblox changed it to be more consistent with the rest of the API where constructors for other types are in camelCase instead of PascalCase.

table.create is typed to require two arguments, but the documentation says it’s optional.

table table.create ( number count, Variant value )
Creates a table with the array portion allocated to the given number of elements, optionally filled with the given value .

image

1 Like

Would love a feature similar to // @ts-expect-error or // @ts-ignore for type errors that we know about and expect/don’t want to deal with.

1 Like

Can you make it so += -= *= /= doesn’t error when using it on a nil value?

Request.Attempt += 1 --Errors if Request.Attempt is nil

--Solution, but its bad because the point of += is to reduce the amount of code typed
if (Request.Attempt) then
	Request.Attempt += 1
else
	Request.Attempt = 1
end

This seems bad because it would become implicit, it can lead to easily introducing bugs in your code base. Most users will want the error to be thrown here so that the issue is made explicit. For example, what if you accidentally misspell the variable name? You’d want an error there, not silently ignored.

Also, the initial value would need to be different for each operator for this to be useful. If the initial value for *= becomes 0, it wouldn’t be useful for your use case. You’d want 0 as default for +=/-= and 1 for *= and /=…

Overall, it seems very messy and implicit if they implement this, I personally would not want that.

8 Likes

Not everything can be 100% safe for developers to use, it’s bad to try do it. If you accidentally misspell a variable name, then that’s a bug in your code that you need to fix and shouldn’t be a reason to not make this change

The second point of the initial variable being different also doesn’t work out. The initial variable will always be 0, never 1

Mob.ExperienceOnDeath *= 2 --Will return 0*2, the expected result if ExperienceOnDeath is nil

Mob.Health /= 2 --Will return 0/2, the expected result if Health is nil

The problem is that these are cherry-picked use cases. I can think of some to counter them easily, e.g.:

Human.SpeedModifier *=2 -- will return 0, so now the human is stuck in place

That change would be ambiguous, not customary, only useful in some situations, and causes bugs in many more situations (when developers unintentionally operate a non-existing member when they did not mean to). It won’t likely be implemented.

5 Likes

This is great I can’t wait for this #updates pdates I think this will, be a great improvement!

I’m a bit confused as to the syntax of importing types.

I want to import a type from a module and only use its name (without Module. before it). Do I do that like this…

local MyTypeProvider = require(ModuleContainingTypes)
type MyType = MyTypeProvider.MyType

Or like this?

local MyTypeProvider = require(ModuleContainingTypes)
type MyType = typeof(MyTypeProvider.MyType)

I would assume the first option would work considering that it’s type = type, rendering the typeof call useless, but I don’t know since both will compile without complaints.

It’s the former. The latter should produce the following diagnostics:

image

If this doesn’t happen for you, it’s likely that this is a consequence of an issue with using non-strict mode in either the module or the script that requires it. We have this on the list to fix.

1 Like

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