|
On 29/07/2022 04:10, Sean Conner wrote:
It was thus said that the Great Lorenzo Donati once stated:Of course you can litter your nested loops with something like if some_condition then goto BAIL_OUT end but this code can be completely understood only knowing where the BAIL_OUT label is placed. It could be placed at the end of the nested loops matrioska structure: for ... for ... for... end end end ::BAIL_OUT::If I'm doing this, then I would restructure the code to be: -- existing code local function foo() for ... for ... for ... if somecondition then return end end end end end foo() I would do the same to make up for the lack of continue: local function foo() while somecondition do ... if somecondition then return foo() -- my "continue" is here end .. end end foo() Remember, Lua can have nested functions.
These are nice tricks (and I really didn't think of those! Cute!). However they lack a bit of clarity. Especially the second, which relies on tail calls.
Ok. They work. And they are structured. However they don't improve the clarity of the code, unless you are used to those idioms. In general I'm wary (readability-wise) of tricks that emulate a "classic/standard" imperative statement (break/continue) with functional tricks.
Moreover, when you have multiple "bail-out" sites, which need to bail-out from different levels, this would not work (whereas "goto" and "break N" would).
BTW, How do function calls/returns impact efficiency? If bailing out is expected to be frequent (maybe form an inner to an intermediate loop) I guess that could affect performance and thrash the GC (I don't know the implementation details of Lua well, but I suppose stack frames and variable slots are (re)allocated/freed).
Yes, any statement is subjected to bugs during refactoring. I argue that "break N" could be less subject to bugs than adjusting goto labels. After all, once you have your algorithm in place and working, it's not so frequent to add/remove a nesting level. It's much more frequent to move some statement around.But you can't be sure until you check it. And this could be annoying/error prone if that nested structure is several editor page long (I assume you have a good reason to have such a deeply nested structure spanning so much code, and that code cannot be refactored in a more readable way avoiding the nesting and maintaining the same efficiency). OTOH, the statement: if some_condition then break 3 endAnd later, that code is embeded one layer deeper, and now your "break 3" is causing some issues because it may not be going where you think it's going. I'm not a fan of the "break 3" option.
Keep in mind that the scenario I'm envisioning is not the one where you have a deeply nested loop/structure just because you didn't apply some amount of functional decomposition or other structure-simplifying practices.
My scenario is about an algorithm that *inherently* needs some degree of deep nesting to be efficient and more readable (some funky math algos are that ways). So I assume that whoever has written the implementation has already eliminated unneeded nesting levels and what is left is the "most" clear and efficient implementation.
-spc