Luau Recap: July 2023

Recently I’ve been running into issues such as types seemingly not being recognized.

Here is an example of my problem:

--!strict

type State = "Standing"|"Running"
type StateInfoTable = {[State]:{Value1:number, Value2:number}}

local StateInfo:StateInfoTable = {
	Standing = {Value1 = 10}, --No warnings even though 'Value2' is not present | No autofill
	["Standing"::State] = {Value1 = 10}, --Warnings due to 'Value2' not being defined | Proper autofill
}

It seems I have to manually define what type the index is?

Is this a known issue?

19 Likes

We discussed this when adding string literals to the type system, and at that moment concluded that there’s odd semantical issues with numbers around NaN that make this a little less useful, and for most cases of idiomatic code we’d like to see code use string literals instead of number literals anyway - iow the section “error catching and control flow” in your post should probably be using strings or booleans.

The one exception to this is what we sometimes refer to as “tuple tables” - a table of a fixed length that has different types for different indices (“finite table” section in your post). We don’t support it right now. We want to eventually support it, but notably this is not the same as supporting numeric literals, and wouldn’t “naturally” fall out of supporting numeric literals in the type system.

14 Likes

Who else thinks reading the updates from Roblox is fun?

I wish there were more updates like this.

16 Likes

Can you please fix that annoying typechecking bug where it says that it expects a table type when you do this:

local Something: BasePart | Decal = nanana

Something.Transparency = 1

This has really been bugging me lately.

Thanks in advance! :slight_smile:

11 Likes

Hilarious you mention this right when I went on to this post to make a comment about this. It’s mildly annoying when you write something and you index similarly to tables and the type checking marks you on it. Maybe my coding habits are terrible and the type checker is telling me what not to do.

Some example:
image

14 Likes

Very nice improvements.

Is there any way these false cyclic dependency warnings will be fixed at any point?

6 Likes

I refuse to believe that our habits are wrong. The type checker should just adapt to how we do it. For as of now, I see it as a bug.

10 Likes

Hi, so using type checking improves the actual performance of code?

6 Likes

Are string interpolation optimizations going to be pursued in the near future?

The inherent improvements towards ergonomics/readability that the use of string interpolation carries shouldn’t come at the expense of runtime performance (to the degree at which it currently does).


It’d be much appreciated if we had a handful of table utility functions (these would go a long way), for example, a table.find overload which accepts a predicate function so it can satisfy a broad range of scenarios including ones where the table is not necessarily a continuous array.

Intended on including more than one example; however, less is more + a predicate func overload to table.find probably has the most merit.

5 Likes

more fire updates from the team, love it!

6 Likes

can we get syntactic sugar for oop pls

3 Likes

Just so you know Luau has a folder in which RFCs are placed which outline upcoming/already implemented features

4 Likes

Like MagmaBurnsV said there, if we get a working example showing the issue, we will be able to investigate it.

4 Likes

‘general typechecking performance’ talks about the time it takes Roblox Studio to perform typechecking.

‘Runtime improvements’ that are mentioned do not require type annotations to work.

But in the future we will have runtime optimizations that rely on type annotations.

4 Likes

I’m not aware of any plans to make performance improvements there.
You should share examples that show a large difference in performance (and not just ""..i vs `{i}` please)

table library methods are implemented in C.
A table.find method with a predicate will actually be slower than Luau implementation because of C->Luau->C transitions for each predicate call.
For this reason, table.foreach and table.foreachi are marked as deprecated now, loop is way better for performance.

There is of course an argument for usability, not performance.
For that, you can just write your own module with helper functions and maybe even share it with the community so that other people don’t have to reimplement the same things.

Maybe we will have a better way to share Luau libraries in the future and provide some Roblox-made starter packs as well, but I can’t guarantee that at current point in time.

6 Likes

@WheretIB

local test = {}
test.__index = test

test.value = "hello"

function test.new()
	local self = setmetatable({}, test)
	
	return self
end


function test:GET()
	self.
end



return test

self. still doesn’t auto complete and suggest me “value”

image

I am sad.

I also can’t do this.
image

4 Likes

Great to here that Roblox had released these functions, will be looking forward to helping facilitate my projects.

5 Likes

Bro the thing yall needa add is, if a nil “self” is detected in a function and is element of a table, then it becomes a Table:FunctionName rather then the conventional Table.FunctionName (which doesn’t pass in self automatically)
image

I can’t go into details why this is important to me, but it really will makes things easier to case check both function and self containing functions

4 Likes

In the scope of Roblox, is there any plans to add support for .luaurc files?

In the case that type definitions through .luaurc files were added, this would give immense power to testing libraries and framework plugins (TestEZ, module loaders, etc.)

The way I see it is by making string attributes with the name '_luaurc' on a script or folder affect either the script or folder’s scripts.


There’s an RFC for this.

In the meantime, here’s my method I use to type idiomatic classes:

local Class = {}
Class.__index = Class

Class.Static = "Hello, world!"

type self = {
	Value: number
}

export type Class = typeof(setmetatable({} :: self, Class))

function Class.new()
	local self = setmetatable({} :: self, Class)
	self.Value = 1
	return self
end

function Class.Method(self: Class)
	print(self.Static)
	return self.Value
end
4 Likes

Yes, we now have someone looking into improving string interpolation performance.

5 Likes