lua-users home
lua-l archive

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

Spaghetti code come from carelessly used unconditionnal jumps (that is the bad goto). I aggree that it can complicate code maintenance, but the (bad) relationship between coders and goto is biased by the C implementation of that statement.

In C there is almost no restrictions. You can put labels where you want, and do anything you want with the program counter, possibly breaking the stack, which pseudo-functionnal C code rely on. If you don't use functions in C, however stupid that may be, there is no reason not to use goto statements. Imperative style don't imply functionnal style, and in pure imperative style you got full control on execution path. (If I had to develop I would say that functionnal coders invented modularization, and they convinced imperative coders that 1) modularization is a good thing and 2) modularization need functions)

Tagged loops translate that concept in a high level code. Breaking normal code execution path is not a good thing, it makes maintenance harder. In the tagged loops, it don't break code execution path. It just simplifies notation for some complicated code execution paths that are already possible in Lua. The proposal is just an idea, and I thought it was interesting enough to send it on the list.

Concerning the dynamic aspect of these tagged loops, I think that there's no reason to limit the break parameter to integers, and for the same reason there should be no reason to limit the loop tag to integers. That not only provide a mechanism to (indirectly) solve the initial problem (break n), that also provide new ways to manage code execution paths at a higher level, way beyond break n or goto "label".

Coroutines are wonderful, bud incorrectly used they can lead to unmaintainable code. That's not a reason to remove them from the language. That would be the same for tagged loops. They provide additionnal mechanisms to the language, there is no reason to use them if you don't want to. And they even could be made optionnal just like coroutines are. Something like (with loop constructs as first class values):

local mywhile = loop(...) -- new loop keyword, creating a loop object, getting tag(s) as parameters
   if #({...})>0 then
      error("Tagged loops not allowed")
while = mywhile

That was just raw ideas to make the language even more flexible, and to eventually trigger interest. Rici's proposal you cited is a bit different, so I may hope to have more success :-) The concept of breaking several loops at once really interested me and I think I'll spend some time to elaborate the above concepts and make them as clean as possible.

-----Message d'origine-----
De : [] De la part de Karel Tuma
Envoyé : 1 novembre 2006 15:05
À : Lua list
Objet : Re: [PATCH] experimental php-like 'break N' to break acrossmultipleloops

On Wed, Nov 01, 2006 at 05:45:28PM +0100, Jerome Vuarand wrote:
> We would just have to tag loops and use that tag in break statements. Example:
> local prefix = "loop"
> local i=1
> local n = 2
> while[prefix..1] i<=10 do
>    for[prefix..2] j=1,10 do
>       if foo then
>          break "loop1"
>       elseif bar then
>          break prefix..n
>       else
>          break -- Would trigger a runtime error, no loop has nil tag
>       end
>    end
> end
tagged/named loops have been discussed already:

rici's solution, except being a bit intrusive to the language, works well (testing the patch against 5.1.1 right now)

nevertheless, all of this is spaghetti code and should be avoided whenever possible. i am of the opinion that multiple scope escape could be useful only in very simple cases when its 100% clear what does the code do... for that, break 2-3 does ok too. named labels would even encourage some people (at least, me) to use such a thing extensively turning maintainability of code to zero. as mentioned in earlier post, such a functionality is basically "goto" and "label:" with few constraints in it.

> Simples "while", "for" and "break" would be syntactic sugars for "while[nil]", "for[nil]", "break nil" respectively. "nil" as a loop label match only "nil" as a break parameter, no wildcard. I used brackets because parenthesis after while/for/repeat would collide with current syntax. For the break it feels more natural to not have any parenthesis, but we could enforce () or [] with existing sugars for string and array constructors.
> I think it's a nice addition. It probably needs internal Lua support because of the tagging of loops, and error detection if break parameter match no current tag.

your tagged loops pushes the whole thing even further by sugesting ability to dynamically specify the point of break scope - performance and implementation complexity issues aside, thats "dynamic" spaghetti code and could turn into real evil. one could suggest even:

while foo do
	while bar do
		goto(foo() and "this" or "that")

eew. creepy, aint it? a bit like BASIC on a C64.
if you know how, one could write highly effective and (!) obfuscated code.

yet its semantically similiar to your suggestion (without the artificial constraint on point of destination)

note that i'm not "lobbying" for break N, it's just a suggestion for those who want quick&dirty&unintrusive solution for _simple_ cases. from language design perspective i stand behind the lesser scope magic, the better. stock lua fullfils that statement to most extent (except really ugly repeat local x = foo() until x).