[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: The meaning of 'sugar' [Forked from Re: Why do we have ipairs?]
- From: Paige DePol <lual@...>
- Date: Wed, 11 Jun 2014 22:01:09 -0500
On Jun 11, 2014, at 9:13 PM, Ross Bencina <firstname.lastname@example.org> 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:
> 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:
> 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).
Ah, okay, we are talking about magic numbers essentially. Though the #defines are just pre-processed into their values before compilation takes place, so the use of MOUSE_UP is only just for the programmer, the compiler would just see `3` (assuming 3, 42, and 66 map to MOUSE_UP, _DOWN, and _MOVE in your example).
>> 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).
Yes, in my case all case values are placed into a Lua table, then when the switch is encountered a single table lookup is done on the value given, if a value is present in the table then that is used as the jump offset to use. I guess in my programming experiences most uses of a switch-like statement have required constant case values, which is what my patch also requires.
>> 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.
Which is not just a problem for Lua, but for any programming language. However, this is not really a failing of switch statements, but rather not having a facility to allow declaration of constants to avoid the use of magic numbers.
Actually, I am just finishing off another patch for Lua that adds a new feature which in turn allows the use of three new keywords: const, macro, and inline. Details will be posted as soon as I've written up the documentation... which will be when the gout in my wrist subsides! :(
>> 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.
My switch-case (computed goto) patch, by itself, does not solve the issue above. Actually, so far as I can tell the issue we are talking about is really a problem with Lua not having a way to declare constant values. The same issue exists for if/elseif blocks as well:
if (x == 3) then
else if (x == 42) then
else if (x == 66) then
With my switch patch the above can be written as follows:
switch and break on x
With my newest patch, which allows creation of constants, the above code could be written as follows, which is a lot more readable:
const MOUSE_UP 3
const MOUSE_DOWN 42
const MOUSE_MOVE 66
switch and break on x
The same constants could be applied to the if/elseif block above as well to increase readability.
Actually, I am not sure how the computed goto has the same failings, essentially the computed goto is using the value of a variable to do a table lookup, if the value is present then perform a jump, if not do some error handling. With a computed goto you are not jumping to a known-at-compile-time value, but rather a computed value at run-time, which is very different than the standard goto which uses static labels and to which jumps are resolved at compile time.
Thank you for your post, I do believe I understand what was meant by the prior post. Though I do wonder if I am still missing something as it seems the problem that exists is more related to the lack of constant declaration than the syntax of switch statements.