According to the "Are you using the Goto statement in Delphi" poll, 40% of Delphi developers will be very upset if they read a sentence where Delphi and Goto and mentioned in the same context.
What's more, 40% of Delphi developers do not even know that Goto exists in Delphi!
In the paper "Go To Statement Considered Harmful" written way back in 1968, Dijkstra argued that unrestricted GOTO statements should removed from higher-level languages.
On the other hand, a paper by Donald Knuth "Structured Programming with Goto Statements" provides quite a few examples where GOTO may be the appropriate tool.
Back to real life. As I said when announcing the mentioned poll on the non-technical Delphi group, the first time I found myself scratching my head was when I found the reason to use a "write-only" property. A few days ago I could not avoid using the Goto statement (without making the code even harder to read), could you believe that?
As it always happens, deadline was approaching. I had a nasty code block that needed to work "yesterday", and as much as I looked upon it ... it appeared unsolvable without the Goto, and without making the code ever more clustered by adding more helper functions - thus harder to read.
This is the situation I had to solve:
The problem here is that one cannot be sure if L is in LL - thus it represents a language or if it is in CC - thus represents a country. This is because LL is a subset of CC!
Of course, L might not be in LL nor in CC.
This is just a schema of the code I used. In real code, a dozen of variables are set in each condition block, objects are created, functions and procedures are being used, more if / for statements are also involved...
Note the usage of Goto, it jumps into an inner "else" block.
If a L's name matches any of the strings in LL and its parent's folder is in CC - we have found a valid CC\LL combination - where a country folder is a parent to a language folder.
If L is NOT in LL but it is in CC - L is a country folder. If L is NOT in LL nor in CC - we have an "ordinary" folder.
Is this a bad Goto usage? I cannot be sure :( Yes, I'm breaking the code flow, but am not jumping to some far away point.
Yet, the fact that this was the first time I used Goto in Delphi, I was sure some other way needs to exist to solve my problem, without code jumps.
The thingy here is that, in the 99% where there is a condition to be tested, I'm accustomed to using the IF statement as:
The second version:
What's more, 40% of Delphi developers do not even know that Goto exists in Delphi!
Goto On Trial!
Goto forces the source code flow execution to be transferred to another point in the code block.In the paper "Go To Statement Considered Harmful" written way back in 1968, Dijkstra argued that unrestricted GOTO statements should removed from higher-level languages.
On the other hand, a paper by Donald Knuth "Structured Programming with Goto Statements" provides quite a few examples where GOTO may be the appropriate tool.
Back to real life. As I said when announcing the mentioned poll on the non-technical Delphi group, the first time I found myself scratching my head was when I found the reason to use a "write-only" property. A few days ago I could not avoid using the Goto statement (without making the code even harder to read), could you believe that?
How I (almost) used Goto in my 10+ years of Delphi Experience
To be honest I was amazed. Just a few days ago, I found myself opening up Delphi help to look for Goto examples and how one can use the Goto statement in Delphi. I knew Goto is here, but I never used it before!As it always happens, deadline was approaching. I had a nasty code block that needed to work "yesterday", and as much as I looked upon it ... it appeared unsolvable without the Goto, and without making the code ever more clustered by adding more helper functions - thus harder to read.
This is the situation I had to solve:
- There's a directory / folder tree.
- The code is recursively walking (processing) the folder tree.
- There's a set of countries, defined as CC = [a,b,c,d,e]
- There's a set of languages, defined as LL = [a,b,c]
- Note that LL is a subset of CC.
- A folder is a "language folder" if its name appears in LL. A folder is a "country folder" if its name appears in CC.
- Every folder needs to be processed in some way.
- Special processing is required for langauge and country folders.
- If a folder is a LL folder its PARENT MUST be a CC folder.
The problem here is that one cannot be sure if L is in LL - thus it represents a language or if it is in CC - thus represents a country. This is because LL is a subset of CC!
Of course, L might not be in LL nor in CC.
First try: using Goto !!
Here's the code I wrote, the code is using Goto.This is just a schema of the code I used. In real code, a dozen of variables are set in each condition block, objects are created, functions and procedures are being used, more if / for statements are also involved...
Note the usage of Goto, it jumps into an inner "else" block.
  if L in LL then     if L.Parent in CC then       Process L as LL C as CC     else       if L in CC then GOTO skip   elseskip:     if L in CC then       Process L as CC     else       Process L as Any Other Folder   end
If a L's name matches any of the strings in LL and its parent's folder is in CC - we have found a valid CC\LL combination - where a country folder is a parent to a language folder.
If L is NOT in LL but it is in CC - L is a country folder. If L is NOT in LL nor in CC - we have an "ordinary" folder.
Is this a bad Goto usage? I cannot be sure :( Yes, I'm breaking the code flow, but am not jumping to some far away point.
Yet, the fact that this was the first time I used Goto in Delphi, I was sure some other way needs to exist to solve my problem, without code jumps.
Second try: No Goto! :)
Here's my second try:   if L in LL then     if L.Parent in CC then       Process L as LL C as CC     else       //add bool variable L_not_LL       Set L NOTin LL   end  if (NOT L in LL) then{if L_not_LL then}     if (L in CC) then       Process L as CC     else       Process as Any Other Folder   end
So, what's the difference here and how come I did not think of such a usage of IFs in the first place?The thingy here is that, in the 99% where there is a condition to be tested, I'm accustomed to using the IF statement as:
  if True then     Do-Something-True   else     Do-Something-False   end
This lead me to using Goto.The second version:
if True then   Do-Something-True endif False then   Do-Something-False end
Ok, this one is Goto-Free, but we have some strange "if" statements here. If I already tested for L in LL, why am I again testing for LL NOT in LL?
SHARE