lua-users home
lua-l archive

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


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).

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 end

  And 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.

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.

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