lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]



On 11/06/2014 23:13, Ross Bencina wrote:
On 12/06/2014 10:44 AM, Paige DePol wrote:
Perhaps you could elaborate on this point a bit as I feel I am
missing something here. Under C switch statements require literal
values yet switch statements are widely used and, as far as I know,
the use of which is not considered bad code.

Hopefully I'm not putting words into Roberto's mouth here. In any case it's not my intention. My impression is as follows:

In C there are two mechanisms for symbolic constants: #defines and enums.

A switch like this:

switch(x){
    case 3: foo(); break;
    case 42: bar(); break;
    case 66: baz(); break;
};

Would be considered bad style. The following (using enum or #defined constants) would not:

switch(x){
    case MOUSE_UP: foo(); break;
    case MOUSE_DOWN: bar(); break;
    case MOUSE_MOVE: baz(); break;
}

The problem is in Lua (unless I'm missing something), you don't have symbolic constants, so it's not possible to "compile" the second form to anything better than a sequence of comparisons. If you use Lua variables, their values are not constant, and so could change each time the switch is executed (hence the equivalence to a linear if/else chain).


In which way does adding symbolic constants allow the optimising of
switch statements?

It allows for a balanced tree, perfect hash and/or static lookup table to be constructed at compile time. This can also be done if the cases are numeric or string literals (perhaps that's what your patch does, sorry I haven't looked at it). But it can not be done if the cases are symbolic (because the values can change), which I would suggest is by far the most common use-case (maybe you have others though).


How would adding a switch optimised for literals
badly impact the code standards for Lua?

By people writing code as in my first example above.


Obviously, as I have created a switch patch for Lua (based on
computed gotos) I have an interest in understanding the points being
raised here! ;)

For the record: I started writing my earlier email to defend the utility of a computed goto, and then realized what Roberto was talking about.

Maybe your patch has a solution that resolves the above.

Ross.





Make it so this is possible:

goto stuff
::label::
print("yay!")
goto exit
::stuff::
f = label
goto f
::exit::

And this:

t=setmetatable({label1, label2},{__index = function() return default end})
goto t[x] -- errors if t[x] doesn't evaluate to a label
::label1::
dostuff()
-- fall thru
::label2::
domorestuff()
goto exit -- break
::default::
dodefault()
::exit::