Using GotoLine in VisualNeo Win: A Controversial but Effective Solution for Complex Code Structures
Maybe I’m wrong, but I think that we all have the idea that a good programmer avoids Goto (in VisualNeo Win GotoLine). Articles, blog posts etc. on the web speak loud and clear about the bad practices of Goto. Spaghetti code is the result, i.e. code that has a “complex and tangled control structure, resulting in a program flow that is conceptually like a bowl of spaghetti, twisted and tangled.” (1).
In the last 30 years, I programmed, I didn’t use Goto or GotoLine (as far as I can recall). In the eyes of gotophobes, I should be proud on it. Should I?
The bad Goto image is nuanced sometimes:
“And when a simple script contains a few gotos well structured to capture missing IF/THEN features with a focus on maintainability and clear code, they’re livable, not some kind of existential crisis.” (2)
and
“Sometimes the careful use of ‘goto’ is a robust and efficient engineering solution. It can also produce simple and much more readable code.” (3)
Last week, I made a text2html converter. Each line of a text file had also to be understood in terms of previous and next lines. I think, you can imagine that nested If-Else constructs (within a Loop) were the result. However, the code was difficult to read and to modify. In addition, the complexity of the code was increased by the fact that lines share much in common and sometimes only have a small difference. Example (4):
The current line is not empty:
– the previous line is empty
– the next line is empty
– the current line starts with a number (section header)
-> surround the line with <h3> and </h3>The current line is not empty:
– the previous line is empty
– the next line is empty or not empty
– the current line starts with an alphabetic character
-> add <p> at the start of the lineThe current line is not empty:
– the previous line is empty
– the current line starts with the character –
– the next line starts with the character –
-> add <ul><li> at the start and </li> at the end of the lineThe current line is not empty:
– the previous line is not empty
– the current line starts with the character –
– the next line is empty
-> add <li> at the start and </li></ul> at the end of the lineThe current line is not empty:
– the previous line is not empty
– the current line ends with a period (.)
– the next line is not empty
-> add <br> at the end of the current line
etc.
You see similarities and differences in the several conditions. Well, as already said, I did not like the nested if/else constructs. So, I tried to change the structure of the code in many ways. At the end, I did like the solution using GotoLine. Some (incomplete) code to give you an idea:
Loop "2" "[no_of_lines]" "[index_current_line]" .(...) If "[line[index_current_line]]" "<>" "[empty]" .extract the first character of the current, previous and next line SubStr "[line[index_current_line]]" "1" "1" "[start_current_line]" SubStr "[line[index_next_line]]" "1" "1" "[start_next_line]" SubStr "[line[index_previous_line]]" "1" "1" "[start_previous_line]" If "[start_current_line]" "=" "-" .............. .remove dash .multiple spaces were removed earlier; so replace -[space] by - StrReplace "[line[index_current_line]]" "-[space]" "-" "[temp]" "" .and delete - StrDel "[temp]" "1" "1" "[temp]" If "[start_previous_line]" "<>" "-" FileWrite "[output_file]" "Append" "!<ul>[#13][#10]<li>[temp]</li>" GotoLine "NEXT_ITERATION_LOOP" EndIf If "[start_next_line]" "=" "-" FileWrite "[output_file]" "Append" "!<li>[temp]</li>" GotoLine "NEXT_ITERATION_LOOP" EndIf If "[start_next_line]" "<>" "-" FileWrite "[output_file]" "Append" "!<li>[temp]</li>[#13][#10]</ul>" GotoLine "NEXT_ITERATION_LOOP" EndIf .etc. .(...) :NEXT_ITERATION_LOOP EndLoop
Simple, readable and straightforward code with short If/EndIf’s without Else part. And each time, an If is evaluated to TRUE, GotoLine “NEXT_ITERATION_LOOP” is invoked and the next if’s are of no concern, i.e. if the job is done, the loop can immediately go to its new iteration.
Speed is in the Goto discussion incidentally a topic. Well, in VisualaNeo Win the GotoLine variant results in faster code: in a Loop with 5000 iterations, a random generator, a Math formula and 10 nested IF/ELSE conditions versus 10 GotoLine commands (5), the GotoLine variant was about 30% faster.
Long live Goto(Line)!
Thanks for reading,
Reinier Maliepaard
Footnotes
(1) Horstmann, Cay (2008). “Chapter 6 – Iteration”. Java Concepts for AP Computer Science.
(2) Berd Wechner (15.01.2022) on https://dev.to/pandademic/is-
(3) https://www.linkedin.com/
(4) Notice that this pseudo code works on a text file that has a specific structure.
(5)
Loop "1" "5000" "[x]" Random "99" "[number]" If "[number]" "<" "10" Math "arctan([number]) + sin([number])/cos([number])" "0" "[result]" GotoLine "NEXT" EndIf If "[number]" "<" "20" Math "arctan([number]) + sin([number])/cos([number])" "0" "[result]" GotoLine "NEXT" EndIf .and so on... :NEXT EndLoop ....................................................................... Loop "1" "5000" "[x]" Random "99" "[number]" If "[number]" "<" "10" Math "arctan([number]) + sin([number])/cos([number])" "0" "[result]" Else If "[number]" "<" "20" Math "arctan([number]) + sin([number])/cos([number])" "0" "[result]" Else .and so on... EndLoop
Comments