Luau Type Checking Beta!

Will the keyword be changed to something else besides type as type is a predefined function (similar to typeof but does not support ROBLOX types)

image

1 Like

Could it be that metatables are not yet “implemented” in the type checking stuff? This is because that the lint complains about not being able to find “say” the table (see snippet). However, this error message does not show when you return your setmetatable() as any (which kind of sounds like bad practice…?)

Sorry if I am missing something, it has been a long day for me :stuck_out_tongue:

--!strict

type World = {message: string, say: (World) => nil}

local world = {}

world.__index = world

function world:say() => nil

print(self.message)

end

function world:new(message) => World

-- Key "say" not found in table

return setmetatable({message = message}, world)

-- However, when returning as any it works (we are probably just supressing the error though)

--return setmetatable({message = message}, world) as any

end

local foo: World = world:new("Hello world")

foo:say()

I presume the type checking only accounts for index explicitly set inside a table, rather than indexes who are indexed via the table having a __index fallback.
image

type cheeseBurger = {pickleCount: number, cheeseType: string}

local specialCheeseBurgerMethods = {
	__index = {
		cheeseType = "Swiss"
	}
}

local cheeseBurgerProperties = {pickleCount = 5}
local myCheeseBurger: cheeseBurger = setmetatable(cheeseBurgerProperties, specialCheeseBurgerMethods)
--// throws warning "W00: Key "cheeseType" not found in table cheeseBurgerProperties

This problem can be easily circumvented by just setting the missing key to nil in your new table. The __index metamethod will still be invoked and everything will work as “intended”

type cheeseBurger = {pickleCount: number, cheeseType: string}

local specialCheeseBurgerMethods =
	__index = {
	    	cheeseType = "Swiss"
	}
}

local cheeseBurgerProperties = {pickleCount = 5, cheeseType = nil}
--// notice how I defined `cheeseType`
local myCheeseBurger: cheeseBurger = setmetatable(cheeseBurgerProperties, specialCheeseBurgerMethods)
3 Likes

Can’t wait for the full release of Luau! I was wondering, since the “syntax of Lua” is changing, will we see operators such as += and -=?

5 Likes

I just get an “unknown symbol Foo.Bar” when I do this.

5 Likes

A similar question was asked on the Luau Recap: November 2019 thread.

There is not intention for a --, ++, += or -= currently. Paraphrased what zeuxcg said.

3 Likes

Pretty sure this is due to spawn() actually passing an argument which is the amount of time it waited before the function ran, similar to wait()

2 Likes

nil already exists as a type (according to op), which I’m pretty sure would work the same way as void.

3 Likes

You should be able to do this with ()

local function f() => ()

end

@joritochip nil should actually be nil, not nothing. (nil is a type, different from nothing)

6 Likes

That gives JS arrow syntax vibes. Not 100% sure if I like it over explicit void return type, but that’s just me

2 Likes

Yesssssss,

This feels so much nicer as I am currently learning other programming languages in class that use this instead of the or syntax (although I kind of like this as well).

2 Likes

Ah, so this is why my scripts using ‘as’ as a variable broke. Thought it was quite strange that changing the variable name to ‘as3’ fixed the problem.

1 Like

This’ll definitely improve the programming experience within Roblox Studio. The new syntax will take some getting used to though.

1 Like

Cool update for scripters like me.

1 Like

Observation: The directive --!strict can be misread as “not strict”, which may lead to confusion.


Request: Allow parameters within function type declarations to be named.

type adder = (a: number, b: number) => (result: number)

Request: Support variadic parameters.

type Function = (params: ...any) => (results: ...any)
type ProtectedCall = (func: Function, ...any) => (ok: boolean, results: ...any)

Question: Are exported types attached to the assigned variable, or the returned value? Does the returned type have to be a table?


Remark: Using : instead of = for type declarations seems cleaner and more consistent.

type Foo = number
local Bar: Foo = 42

-- vs

type Foo: number
local Bar: Foo = 42

Request: The type keyword conflicts with the well-established type identifier. I doubt the type() function is going away, so resolving this conflict requires an annoying increase in parser complexity. Instead, change the keyword to typedef or something. Please don’t become javascript. Please don’t become javascript.


Observation: Type declarations are scoped.

function func()
	type foo = number
	-- foo exists only within function-block.
	if true then
		type bar = number
		-- bar exists only within if-block.
	end
end

Observation: Studio crashes with the following script:

--!strict
function Vector3:Foo()

end

Remark: In general, there’s a ton of uncertainty. A proper specification with a grammar would be great.


Observation: Types are really hard. I’m scared.

31 Likes

Interesting update!

One minor complaint, arithmetic operations with string and number operands only work in situations where the string represents a number, but Luau currently doesn’t flag this at all and all situations give no errors:

image

It would be nice if we could get a warning or something instead. A warning system I think would be a fine addition to Luau – just as long as we have some control over each individual warning (e.g. right click → ignore or something), and also that there are enough warnings to grant such a system lol

2 Likes

With updates to the lua vm such as type checking, will we ever see a constant keyword or something similar? Essentially throw an error if you try to reassign a variable that is set to constant.

local constant cheeseBurger = 5

cheeseBurger = 2

Attempt to reassign variable: “cheeseBurger”

Kinda like JS which has its const keyword:
image

4 Likes

It actually doesn’t. We may have to reevaluate the as issue as @Tomarty noted above, but type is safe to parse because it has to be followed by an identifier, and after parsing the first identifier in the statement (“type”) you already need to parse the next token to figure out what it is you’re parsing, assignment or function call or something else.

On the flip side, introducing keywords is really hard for us due to backwards compatibility. Guess why we haven’t added continue :-/

13 Likes

Just so I am not missing anything here, the new syntax won’t be enabled without --!strict?

and yeah are we gonna get function overloading?

1 Like

We do plan to rebuild intellisense to work through type information, but this is not part of this beta.

3 Likes