infratec wrote:Very simple rule:
Don't use Goto and Gosub
These relics are from an earlier time of programming.
They should be avoided and maybe should use compiler warnings to make this clear.
I, personally, also avoid several ProcedureReturns in one procedure.
Obviously It's a personal opinion, but I hope you don't mind discussing this further. It's helpful for newer programmer to see discussions around the principles.
My advice to programmers: don't use goto until you understand how the stack works. You should learn how the stack works.
I'm a strong advocate of using multiple returns in one procedure when it makes the flow of the code cleaner and clearer.
I consider the Single Entry Single Exit principle another relic from an earlier time. We can depend upon PB to clean up after us, so why waste time adding additional variables or flags?
For example, the common idiom in PureBasic is to wrap the use of resources in an If Statement, like this example from the File documentation:
Code: Select all
If CreateFile(0, "PureBasicTestFile.txt")
WriteStringN(0, " This is a PureBasic file test")
WriteString(0, "Now it's on ")
WriteString(0, "the same line.")
CloseFile(0)
Else
MessageRequester("PureBasic", "Error: can't write the file", 0)
End
EndIf
Personally I don't like this approach. What if I want to open two files and then a window to display the results. You end up with a pyramid of doom:
Code: Select all
If ... Create File 1 ...
If ... Create File 2 ...
If --- Open Window ...
... Lots of code ...
Else
... Error ...
EndIf
Close File 2
Else
... Error ...
EndIf .
Close File 1
Else
... Error ...
EndIf
Procedure Return
The Error handler is miles away from the condition, and there's a risk that I'll add code somewhere I shouldn't. For example, some wrap up code after the window closes. It's easy to forget the right place to put resource clean up.
Refactoring in particular becomes difficult, because of the need to untangle the code and it's preconditions.
I much prefer to use precondition gates like this:
If Not CreateFile...
... Error ...
ProcedureReturn
EndIf
If Not CreateFile...
... Error, close file 1 ...
ProcedureReturn
EndIf
If Not OpenWindow...
....Error, close file 2 ...
ProcedureReturn
EndIf
... Lots of code ...
... I want to avoid ProcedureReturns here because I don't want to repeat the clean up. Sometimes I might use a Goto to jump to that clean up. ...
... The clean up. Closing files, etc. ...
ProcedureReturn
The precondition gates sit at the top and it's clear what is happening. By the time I get to my main body of code I know that everything has gone well. When I'm refactoring the methods preconditions are separated and easy to move.
It's a matter of personal taste. I value writing code that is clean and clear, even if it means using constructs that are considered harmful.
Here are some more discussions on the topic:
Regards,
Ged