Switch statements for LuaU

no passthrough or handling default cases :rage: :rage: :rage: :rage:

here is my implementation:

local default = newproxy()
local function switch(case)
    return function(callbacks) --[[ I can't think of any way to implement passthrough without funky syntax ]]
        return (callbacks[case] or callbacks[default] or error(`No default case or handler for {case}`)()
    end
end


switch(10){ -- This is legal in Lua(u) and considered calling with a table
 [10] = function()
  print("Is 10")
 end
 [default] = function()
  print("Cannot be handled")
 end
}
5 Likes

more strict meaning less chances for confusion etc to occur

2 Likes

but yes your syntax is more similar, iā€™m probably going to turn it into a module and use it :sunglasses:

2 Likes

You should OS it so no one has to go through jerryrigging this, I feel that module would be useful to a lot of people

2 Likes
return function (case : string | number)
    return function(callbacks : {[any] : () -> any})
        return (
            callbacks[case]
                or
            function()
                print(case, 'is not a case of switch')
            end
        )()
    end
end

here you go lol

3 Likes

usage will apply the same

local switch = require(...)

switch (10) {
  [10] = function()
    print('chat its 10')
  end;
  [15] = function()
    print('chat what the filip its not 10 its 15')
  end
}
3 Likes

One cool thing about switch statements is that they have much better perfomance compared to if else statements.
Are switch statements in lua required? Maybe. Would it be cool to have them? Yes.

2 Likes

Switch statements are fast in other languages because they can be optimized into a simple look-up table where each value tells the system to ā€œjumpā€ to a specific section of the code. I feel like Luau could have these optimizations for if statements you could replace with a switch statement in other languages, though, so I donā€™t really think optimization is an advantage to adding switch statements.

But yeah I think it would be cool to use them instead of long else-if chains, but Iā€™d be content with a custom implementation like the ones shared in this thread.

2 Likes

However, you can implement switch fallthrough, something currently hard to do with if statements. Thatā€™s the main reason Iā€™d want to use switches.

3 Likes

I would also like to add that switch statements have the potential to be faster than if statements, as they can be optimized, taking into account that theyā€™re only going to check for equality

2 Likes

As said before, even if we implemented something like switch, it would almost certainly not have fall through.

2 Likes

If we can make these optimizations with switch, we can make them with normal if statements as well. Thereā€™s no reason we canā€™t analyze something like this:

if color == "red" then
  -- red
elseif color == "green" then
  -- green

ā€¦the same way we would an ordinary switch when it comes to optimization. I cannot speak for if we do any kind of jump table optimizations or whatnot today, thoughā€“I donā€™t know that part.

4 Likes

Yep, I saw that right after I made the post. Whatā€™s the reasoning behind not wanting to implement it? I understand other modern languages donā€™t use it but I donā€™t see why Luau has to copy others (itā€™s already pretty unique as is).

2 Likes

From what I have seen, some people here donā€™t really know that a switch/case statement checks one variable only. Similar to other solutions here, this is how I deal with it:

local function f1(params)
	-- Do something
end

local function f2(params)
	-- Do something
end

local function f3(params)
	-- Do something
end

local function f4(params)
	-- Do something
end

local functionCallTable = {
	[value 1] = f1;	
	[value 2] = f2;	
	[value 3] = f3;	
	[value 4] = f4;
}



if functionCallTable[check value] ~= nil then
	functionCallTable[check value](params)
else
	-- Do something else
end

As you can see, there are ways around a missing switch/case statement. I personally would love to have a switch/case statement in LUA, but it must be compatible with existing code. Someone mentioned that if switch and case became reserved words, a lot of code would break, and I donā€™t think itā€™s worth it. With that being said however, thereā€™s nothing that says that switch/case can be called something else.

Another thing that comes to mind is the LUA JIT Compiler: Have it look for the above patterns and use a switch/case internally. That will require complex alterations to the lexicographic analyzer and the parser. However, an alternative to this is to modify the optimizer. When the AST (Abstract Source Tree) is analyzed, the optimizer can look for these patterns and optimize it accordingly for the code generator.

Or add a directive that can be placed in the source code to tell the compiler that this construct is a switch/case pattern.

There are always alternatives.

One thing that I want to point out about the if-then-elseif-else statement chain is the benefit of being able to check completely different cases with completely different variables within the chain.

2 Likes

Matching naturally cover a wider use case than switch statement. Things like table patterns, as an example. It makes more sense to only add one of them to the language, so it seems reasonable to add pattern matching.

3 Likes

if/else statements are vroom in Luau, idk what optimisation black magic they use for that.

I have a module with over 30 if-else branches and its very readable. idk why Luau needs another control flow option when the existing one works perfectly.

Just add a line of whitespace between the end of a branch and a new condition

6 Likes

What you have mentioned is more of a coding style issue than anything else.

1 Like