Luau Recap: January 2022

Luau is our programming language that you can read more about at https://luau-lang.org.

Find us on GitHub!

Performance improvements


The implementation of tostring has been rewritten. This change replaces the default number->string conversion with a new algorithm called Schubfach, which allows us to produce the shortest precise round-trippable representation of any input number very quickly.

While performance is not the main driving factor, this also happens to be significantly faster than our old implementation (up to 10x depending on the number and the platform).

Make tonumber(x) ~2x faster by avoiding reparsing string arguments.

The Luau compiler now optimizes table literals where keys are constant variables the same way as if they were constants, eg

local r, g, b = 1, 2, 3 
local col = { [r] = 255, [g] = 0, [b] = 255 } 

Improvements to type assertions


The :: type assertion operator can now be used to coerce a value between any two related types. Previously, it could only be used for downcasts or casts to any . The following used to be invalid, but is now valid:

local t = {x=0, y=0} 
local a = t :: {x: number}

Typechecking improvements


An issue surrounding table literals and indexers has been fixed:

type RecolorMap = {[string]: RecolorMap | Color3} 
local hatRecolorMap: RecolorMap = { 
      Brim = Color3.fromRGB(255, 0, 0), -- We used to report an error here 
      Top = Color3.fromRGB(255, 0, 0) 
}

Accessing a property whose base expression was previously refined will now return the correct result.

Linter improvements


table.create(N, {}) will now produce a static analysis warning since the element is going to be shared for all table entries.

Error reporting improvements


When a type error involves a union (or an option), we now provide more context in the error message.

For instance, given the following code:

--!strict 
type T = {x: number} 
local x: T? = {w=4}

We now report the following:

Type 'x' could not be converted into 'T?'
caused by:
  None of the union options are compatible. For example: Table type 'x' not compatible with type 'T' because the former is missing field 'x'

Luau now gives up and reports an *unknown* type in far fewer cases when typechecking programs that have type errors.

New APIs


We have brought in the coroutine.close function from Lua 5.4. It accepts a suspended coroutine and marks it as non-runnable. In Roblox, this can be useful in combination with task.defer to implement cancellation.

REPL improvements


The luau REPL application can be compiled from source or downloaded from releases page. It has grown some new features:

  • Added --interactive option to run the REPL after running the last script file.
  • Allowed the compiler optimization level to be specified.
  • Allowed methods to be tab completed
  • Allowed methods on string instances to be completed
  • Improved Luau REPL argument parsing and error reporting
  • Input history is now saved/loaded

Thanks


A special thanks to all the fine folks who contributed PRs over the last few months!

Contribution guide

90 Likes

This topic was automatically opened after 10 minutes.

LuaU is going places and just getting better, and I can’t wait to see more improvements and optimizations!

(please don’t quote this if in like 5 years something goes horribly wrong <3)

14 Likes

Even if it was just updating the docs on coroutine.close. It’s cool to see how the community really helps keeping this project up to date!

I would like to report a bug that I’ve noticed recently, if a script is requiring one or more large scripts, Luau’s Language Server can cause Studio to hang for a minute or longer, my friend has also reported not being able to open relatively small scripts since this change.

2 Likes

Lots of complaints about the change in tostring formatting, but I personally find it more useful. Especially loving the addition of coroutine.close and improvements to typechecking.

Keep up the good work!

4 Likes

I saw an implementation by some staff / known person whatever. I don’t know these ppl.

But they implemented in a way on which it can break and someone can resume that thread before it’s actually closed.

The proper implementation would be this:

local function exit()
    task.defer(
        coroutine.close, coroutine.running()
    )
    coroutine.yield()

    error("Attempt at resuming dead coroutine")
end
2 Likes

Glad to see more and more changes being made with the help of the community. Keep up the great work!

2 Likes

LuaU is getting more interesting by the day, I’m looking forward towards the new improving elements! Thank you all the contributors for these advanced new performance improvements. We honestly needed this and I really am glad that problems with the table literals and indexers are fixed because that was something that I had to deal with once and I’m glad that this is being worked on and lets see what good features come next for Roblox!

1 Like

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