Is it possible to always eliminate goto's? - c#

While making everthing with goto's is easy (as evidenced by f.ex. IL), I was wondering if it is also possible to eliminate all goto statements with higher level expressions and statements - say - using everything that's supported in Java.
Or if you like: what I'm looking for is 'rewrite rules' that will always work, regardless of the way the goto is created.
It's mostly intended as a theoretical question, purely as interest; not as a good/bad practices.
The obvious solution that I've thought about is to use something like this:
while (true)
{
switch (state) {
case [label]: // here's where all your goto's will be
state = [label];
continue;
default:
// here's the rest of the program.
}
}
While this will probably work and does fits my 'formal' question, I don't like my solution a single bit. For one, it's dead ugly and for two, it basically wraps the goto into a switch that does exactly the same as a goto would do.
So, is there a better solution?
Update 1
Since a lot of people seem to think the question is 'too broad', I'm going to elaborate a bit more... the reason I mentioned Java is because Java doesn't have a 'goto' statement. As one of my hobby projects, I was attempting to transform C# code into Java, which is proving to be quite challenging (partly because of this limitation in Java).
That got me thinking. If you have f.ex. the implementation of the 'remove' method in Open addressing (see: http://en.wikipedia.org/wiki/Open_addressing - note 1), it's quite convenient to have the 'goto' in the exceptional case, although in this particular case you could rewrite it by introducing a 'state' variable. Note that this is just one example, I've implemented code generators for continuations, which produce tons and tons of goto's when you're attempting to decompile them.
I'm also not sure if rewriting in this matter will always eliminate the 'goto' statement and if it is allowed in every case. While I'm not looking for a formal 'proof', some evidence that elimination is possible in this matter would be great.
So about the 'broadness', I challenge all the people that think there are 'too many answers' or 'many ways to rewrite a goto' to provide an algorithm or an approach to rewriting the general case please, since the only answer I found so far is the one I've posted.

This 1994 paper: Taming Control Flow: A Structured Approach to Eliminating Goto
Statements proposes an algorithm to eradicate all goto statements in a C program. The method is applicable to any program written in C# or any language that uses common constructs like if/switch/loop/break/continue (AFAIK, but I don't see why it wouldn't).
It begins with the two simplest transformations:
Case 1
Stuff1();
if (cond) goto Label;
Stuff2();
Label:
Stuff3();
becomes:
Stuff1();
if (!cond)
{
Stuff2();
}
Stuff3();
Case 2
Stuff1();
Label:
Stuff2();
Stuff3();
if (cond) goto Label;
becomes:
Stuff1();
do
{
Stuff2();
Stuff3();
} while (cond);
and builds on that to examine each complex case and apply iterative transformations that lead to those trivial cases. It then rounds off with the ultimate gotos/labels eradication algorithm.
This is a very interesting read.
UPDATE: Some other interesting papers on the subject (not easy to get your hands on, so I copy direct links here for reference):
A Formal Basis for Removing Goto Statements
A Goto-Elimination Method And Its Implementation For The McCat C Compiler

A situation where a goto can be avoided, but I think it is better to use it:
When I need to exit a inner loop and the loop:
for(int i = 0; i < list.Count; i++)
{
// some code that initializes inner
for(int j = 0; j < inner.Count; j++)
{
// Some code.
if (condition) goto Finished;
}
}
Finished:
// Some more code.
To avoid the goto you should do something like this:
for(int i = 0; i < list.Count; i++)
{
// some code that initializes inner
bool conditon = false;
for(int j = 0; j < inner.Count; j++)
{
// Some code that might change condition
if (condition) break;
}
if (condition) break;
}
// Some more code.
I think it looks much nicer with the goto statement.
The second situation is okay if the inner loop was in a different method.
void OuterLoop(list)
{
for(int i = 0; i < list.Count; i++)
{
// some code that initializes inner
if (InnerLoop(inner)) break;
}
}
bool InnerLoop(inner)
{
for(int j = 0; j < inner.Count; j++)
{
// Some code that might change condition
if (condition) return true;
}
return false;
}

I have some practical experience of attempting to take an unstructured program (in COBOL, no less) and render it as structured by removing every instance of GOTO. The original programmer was a reformed Assembly programmer, and though he may have known about the PERFORM statement, he didn't use it. It was GOTO GOTO GOTO. And it was serious spaghetti code -- several hundred lines worth of spaghetti code. I spent a couple of weeks worth of spare time trying to rewrite this monstrous construct, and eventually I had to give up. It was a huge steaming pile of insanity. It worked, though! Its job was to parse user instructions sent in to the mainframe in a textual format, and it did it well.
So, NO, it is not always to possible to completely eliminate GOTO -- if you are using manual methods. This is an edge case, however -- existing code that was written by a man with an apparently twisted programming mind. In modern times, there are tools available which can solve formerly intractable structural problems.
Since that day I have coded in Modula-2, C, Revelation Basic, three flavors of VB, and C# and have never found a situation that required or even suggested GOTO as a solution. For the original BASIC, however, GOTO was unavoidable.

Since you said it's a theoretical question, here is the theoretical answer.
Java is Turing complete so of course, yes. You can express any C# program in Java. You can also express it in Minecraft Redstone or Minesweeper. Compared to these alternatives expressing it in Java should be easy.
An obviously more practical answer though, namely an intelligible algorithm to do the transformation, has been given by Patrice.

I don't like my solution a single bit. For one, it's dead ugly and for two, it basically wraps the goto into a switch that does exactly the same as a goto would do.
That's what you're always going to get when looking for a general pattern which can replace any use of goto, something which does exactly the same as a goto would do. What else could it be? Different uses of goto should be replaced with best matching language construct. That's why constructs as switch statements and for loops exist in the first place, to make it easier and less error prone to create such a program flow. The compiler will still generate goto's (or jumps), but it will do so consistently where we will screw up. On top of that we don't have to read what the compiler generates, but we get to read (and write) something that's easier to understand.
You'll find that most compiler constructs exist to generalize a specific use of goto, those constructs where create based on the common patterns of goto usage which existed before it. The paper Patrice Gahide mentions sort of shows that process in reverse. If you are finding goto's in your code you are either looking at one of those patterns, in which case you should replace it with the matching language construct. Or you are looking at essentially unstructured code in which case you should actually structure the code (or leave it alone). Changing it to something unstructured but without goto can only make matters worse. (The same generalization process is still going on by the way, consider how foreach is being added to compilers to generalize a very common usage of for...)

Related

Fall from one case to another using goto

I have read multiple articles saying using goto is a massive no no in programming. But some specifically indicate that it's the abuse of goto that is wrong and that in some cases, like switch cases, it's the intended use.
So my question to you is, for future reference, which is best practice/more efficient.
this:
switch (a)
{
case 1:
//Something specific for case 1
break;
case 2:
//Something specific to default and case 2
break;
default:
//Something specific for default
goto case 2;
}
or this:
switch (a)
{
case 1:
//Something specific for case 1
break;
case 2:
//Something specific to default and case 2
thatFunction();
break;
default:
//Something specific for default
thatFunction();
break;
}
void thatFunction() { /*Case 2 stuff*/ }
EDIT: These two switch statements are examples, the actual code contains many more cases.
Everyone at my workplace has either never used goto or say they've only heard to never ever use it. So I came here for a definitive answer. I'm looking for an answer and an explanation or links to one.
Thanks,
You always need to understand the reasoning behind any "no-no" (or "yes-yes"). That way you can understand where it makes sense to apply the rule, and where it doesn't.
The big fight against goto goes all the way back to programming without true procedures and functions, or even something as simple as a loop. goto allowed you to jump from anywhere to anywhere else, and it was extremely hard to think about what it actually means. "Don't use goto" was part of the movement to structured code, as opposed to lots of jumps all the way around the code; using things like for (int i = 10; i > 0; i--) { ... } for iteration, rather than if (i-- > 0) goto startLoop;.
In a switch, goto is constrained - it can only do one thing, execute a branch of the switch statement. In fact, in C#, even outside of a switch statement, goto is very constrained and safe, and rarely has any of the implications that were assumed when the "Goto is evil" movement started. That doesn't mean you should start replacing all your loops with gotos, of course :)
Now, if things are getting this complicated, it might be that a switch isn't a good solution for your problem in the first place. Perhaps you can use a different structure to do what you're trying to do - there's many ways to do polymorphism and/or code reuse in C#, and one of those might be a better approach that will allow you to use clearer code to do what you're trying to do. But we can't really help you with that :)
The answer is that logic going in circles is best kept to religion and politics. Your default is really case 2, which means that case 2 is really just default. While it's possible that there's some execution in case 2 that doesn't occur in default, it's extremely rare that you'd ever need to do anything other than an if condition in your default case. Further, in troubleshooting the result of your switch evaluation cannot be immediately determined if you loop backward up the case chain. Imagine your stack trace, too.
There are times to use goto, but these are often in exceptional cases (see what I did there) where you need to immediately execute an action (such as logging something going wrong on another thread) before breaking a run condition or infinite loop. The general rule with goto is the same as with preprocessor commands. If there's another way you can do the same effective thing, you should use the other way for logical continuity and maintainability.

Why not GOTO Statement? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I am doing Masters in Software Engineering. From College to University i heard from my teachers and instructors that never use GOTO statement in Programming Language.According to
Software Engineering By D. Sundar
USE of goto statements makes a program unstructured and makes it very
difficult to understand.
and i also read the same in book by MICROSOFT on its first page that never use GOTO Statmement in Programming.
It always arises question in my mind that if we are instructed that never use GOTO Statement then why it is the part of many common programming languages ?
At least for some programming languages (none of which I'm the designer of, obviously) like C and C++, I imagine it's there because it
Closely models what the hardware really can do, which is kind of the goal in these languages.
Is sometimes actually useful and better than more "structured" approaches.
The most common example of when goto is often considered good is when doing nested error/resource management in C. See for instance the Linux kernel, a fairly large and successful C project which uses goto for this purpose.
You want to read the seminal "Go to statement considered harmful" by Edsger W. Dijkstra (1968!)
There is no goto statement in java. The Java keyword list specifies the goto keyword, but it is marked as "not used".
You instructed not to use goto because they want to teach you how to write code.
but sometimes goto can be useful.
when you want to break at once from a multi-level loop. you can add an exit condition to each step. and you can use goto endloop
look at this example: (psaudo code)
while(cond1){
while(cond2){
while(cond3){
if(want to break){
goto endloop
}
do something
if(want to break2){
goto endloop
}
}
do something
}
do something
}
endloop:
do something else
without the goto it may look like this:
while(cond1 && exitloopflag){
while(cond2 && exitloopflag){
while(cond3 && exitloopflag){
if(want to break){
exitloopflag = true;
break;
}
do something
if(want to break2){
exitloopflag = true;
break;
}
}
if(exitloopflag)
break;
do something
}
if(exitloopflag)
break;
do something
}
do something else
so we can argue which code readability is better...
The presence of goto in any modern programming language is largely vestigial, sort of like the human appendix. Its functionality has been replaced with conditional and looping control structures (if-then-else, for/while/loops, switch/case statements, etc.). It hangs around in languages like C and C++ because there are edge cases where it's still quite useful, such as breaking out of a deeply nested loop:
for (...)
{
for (...)
{
for(...)
{
...
// hit a fatal error, need to break out to outermost scope
goto whoopsiedoodle;
}
}
}
whoopsiedoodle:
...
However, its use is discouraged for a number of very good reasons: since it can branch either direction in a function, it can destroy the ability to debug code by simple inspection. For example, given the following snippet:
i = 1;
label: printf("i = %d\n", i);
What value gets printed for i? How many times will that print statement be executed? Until you account for every instance of goto label;, you can't know. Now, imagine the code is structured something like the following:
i = 0;
goto label;
foo: ...
...
i = 1;
label: printf("i = %d\n", i);
...
goto foo;
...
Now, imagine several dozen (or even several hundred) lines of code for each ... in the snippet above. Also imagine the presence of 10 or 11 other labels scattered throughout, with associated goto statements scattered largely at random. This is modeled after some real-world code I encountered early in my career. The only way to debug code like this is to trace the execution, line by line, accounting for every goto along the way. This code was badly written to begin with (a monolithic, 5000-line main function, literally hundreds of separate variables, some declared at file scope, some local to main, and other atrocities), but the use of goto was a force amplifier that turned merely bad code into an unmaintainable sludge. This code defined "brittle"; we literally could not change a single line of it without breaking something else.
Excessive use of goto can also hinder the compiler's ability to optimize code. Modern compilers are quite smart, and can take advantage of structured programming techniques to do effective branch prediction or unroll loops for real performance gains. Code like the above is almost impossible for the compiler to optimize. That real world code that the above snippet is modeled on? We tried to compile it with optimization flags turned on (gcc -O1). The compiler ate all available RAM, then it ate all available swap, causing a kernel panic.
We told the customer they would either need to buy faster hardware, or allow us to rewrite the entire thing from the keel up. They wound up buying faster hardware.
goto can be used effectively, as long as you obey the following rules:
Branch forward only.
Never branch into the body of a control structure (i.e., don't bypass the if, for, while, or switch condition).
Avoid branching over large sections of code.
Id like to give an explanation, why you should use GOTO very carefully.
I do not say GOTO is a bad statement at all, that is one of the reasons, why it is still implemented in C++ (and due to compatibility reasons to C), in JAVA its only reserved as a keyowrd.
I can show you examples where GOTO is the best solution (in my point of view)
But you should prevent using it due to the following reason:
(Taken, translated and modified by me, from the Book Ohne C Zu C++)
Imagine you play a game like Settlers of Catan, wherever you go, anyone has its own
rules.
That is ok, you just need to learn the rules and then you can play with them.
But what is if they will not teach u there rules, and just use it? you will loose the fun in gaming with
them very fast.
A goto statement is like a new Settler of Catan rule.
Programming is hard enough to understand when you can reliably assume that you start at >the top, execute 1 line at a time, going down, one line at a time.
Using a goto statement throws that assumption out the window, and all of the sudden, the "game! is uncertain. It's a new and uncertain rule.
In some languages, it is used for exception handling (e.g. VBA)
Java has goto as a keyword but it is doing nothing. I belivie they did this, that you can't name anything goto
However, in some cases goto can be useful!
goto is explicitly not allowed in Java. It is there in other languages because it is easy to implement as it is a simple instruction in machine code, not because it is a good idea.
BTW You can do something like a goto in Java. See if you can easily work out what this simple example does, and if you can't you are answering your own question. If it's obvious to you what this does and how it works, you have to consider than many would find this confusing.
FOUND: {
for(String s: list)
if(s.contains(like))
break FOUND;
System.out.println(like + " not found");
}
Goto statements model machine code; there are very limited flow-control constructs in machine code, and there is no way to write a significant machine code program without the equivalent of a goto.
The original high-level languages, such as COBOL and FORTRAN, had Gotos because that's how people knew to control their flow from doing machine code on their machines. The C language was also created with one, though years later, partially because that language was specifically created to be easy to compile to efficient machine code -- some of the C language constructs, such as the increment/decrement operators, are there because the machine for which C was originally created had those sub-operations in its machine code. It can be said that C is not a high-level language, it is a structured assembler (and there's nothing wrong with that, it was ahead of its time, and still highly useful).
What Dijkstra and others figured out, though, is that (1) it isn't necessary to have a goto if you have sufficient higher-level constructs for flow control, and (2) it is horribly error-prone. I remember reading that there were analyses of code that found that a goto statement was 9 times more likely to be in error than any other kind of statement.
It is ironic because it is not the least difficult to understand conceptually what the statement is doing; it's just that the uses programmers make of it too often turn out to make the program overall harder to understand.
Goto is permitted when we're jumping
out of a scope,
just next behind the scope close.
All other cases are invalid (jumping into a cycle, jumping into the middle of an if-block, jumping into another function, OMG, happy Halloween).
As there are several way to break a scope, like break, break label, return etc, there is no situation where pure goto must be used (except some early languages which does not support some of above, usually break label).
Other words, goto has not disappeared (it's impossible to write a program without changing the order of execution), we just make distinctions by using different keywords for different types of execution path. Goto now has special cases, which have own keywords. It also makes code easier to understand.

Use of Goto within lexer/parser

I have a lexer/parser pair (which I cribbed off someone else years ago). I am going to be adding a couple of features and thought I would first standardise the use of while(true) containing multiple if/else if/else vs a switch which uses a goto to jump back to before the switch.
(Before the flames start, I don't normally use goto as its evil etc. etc.)
The problem with a while(true) and a nested switch is that the break only breaks out of the switch and cannot get outside the while.
I have done some searching here and seen suggestions to use a return from inside the switch. Whilst this would work in some cases, in others, there is some processing after the while but before returning. Duplicating this code in multiple places doesn't really appeal.
I could also introduce a boolean flag and use that in the while statement to decide whether to break out of the while but that also doesn't appeal as it adds noise to the code.
The current way in the parser of using if/else if/else instead of an inner switch works but I do have a preference for a switch if possible.
The lexer code in general seems to get around this by removing the while(true) and putting a label just before the switch start and using goto to continue the loop. This leaves break meaning stop the loop and, to be honest, seems the cleanest way but does involve the dreadead goto.
Going back to the while(true), I can also see a third way. Use a label after the while(true) and let the switch code use goto to get to it when the loop should end. Break would then mean exit the switch but continue the loop.
So what are the panels views on this? Is goto too abhorrent to use? Or is it OK when there is just a single label to jump to and reduces indenting and produces otherwise clear code? Should parsers/lexers get special license to use gotos?
I can provide some sample code if it would help.
Use of GOTO in disciplined ways is fine. Languages which don't allow breaks out of arbitrarily nested block structures cause this question to be raised repeatedly, since the 1970s when people beat the question of "what control flow structures should a langauge have" to death. (Note: this complaint isn't special to lexers/parsers).
You don't want the scheme with boolean; it just adds extra overhead to the loop checks and clutters the code.
I think you have this problem:
<if/while/loop head> {
<if/while/loop head> {
...
if <cond> <want to break out all blocks>
...
}
}
The proper cure with a good language is:
blocks_label:
<if/while/loop head> {
<if/while/loop head> {
...
if <cond> exit blocks_label;
...
}
}
if the exit construct exists in your language, that exits
the blocks labelled by the named label. (There's no excuse
for a modern langauge to not have this, but then, I don't
design them).
It is perfectly satisfactory to write, as a poor man's substitute:
<if/while/loop head> {
<if/while/loop head> {
...
if <cond> goto exit_these_blocks;
...
}
}
exit_these_blocks: // my language doesn't have decent block exits
On occasion you'll find a language that offers
break <exp>
where exp is usually a constant whole number, meaning, "break out of exp nested blocks". This is an astoundingly stupid idea, as some poor maintainer may later come along an insert another block somewhere in the stack, and now the code does crazy things. (In fact, this exact mistake in a telco switch took out the entire East Coast phone system about 20 years ago). If you see this construct in your langauge, use the poor man's substitute instead.
Within parsers the use of GOTO is perfectly reasonable. When you get down to a base level, the loops and conditions etc are all implemented as gotos, because that is what processors can do - "take the next instruction to be executed from here".
The only problems with gotos, and the reason they are so often demonised, is that they can be an indication of unstructured code, coming form unstructured thinking. Within modern high level languages, there is no need for gotos, because all of the facilities are available to structure code well, and well structured code implies at least some structured thinking.
So use gotos if they are needed. Don't use them just because you can't be bothered to think things through properly.

Does anyone still use [goto] in C# and if so why? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I was wondering whether anyone still uses the "goto" keyword syntax in C# and what possible reasons there are for doing so.
I tend to view any statements that cause the reader to jump around the code as bad practice but wondered whether there were any credible scenarios for using such a syntax?
Goto Keyword Definition
There are some (rare) cases where goto can actually improve readability. In fact, the documentation you linked to lists two examples:
A common use of goto is to transfer control to a specific switch-case label or the default label in a switch statement.
The goto statement is also useful to get out of deeply nested loops.
Here's an example for the latter one:
for (...) {
for (...) {
...
if (something)
goto end_of_loop;
}
}
end_of_loop:
Of course, there are other ways around this problem as well, such as refactoring the code into a function, using a dummy block around it, etc. (see this question for details). As a side note, the Java language designers decided to ban goto completely and introduce a labeled break statement instead.
I remember this part
switch (a)
{
case 3:
b = 7;
// We want to drop through into case 4, but C# doesn't let us
case 4:
c = 3;
break;
default:
b = 2;
c = 4;
break;
}
To something like this
switch (a)
{
case 3:
b = 7;
goto case 4;
case 4:
c = 3;
break;
default:
b = 2;
c = 4;
break;
}
Refer This
I use it extensively in Eduasync to show the kind of code that the compiler generates for you when using async methods in C# 5. You'd see the same thing in iterator blocks.
In "normal" code though, I can't remember the last time I used it...
The compiler uses goto statements in various pieces of generated code, for example in generated iterator block types (generated when using the yield return keyword - I'm pretty sure that the generated XML serialisation types also have a few goto statements in there somewhere too.
See Iterator block implementation details: auto-generated state machines for some more details on why / how the C# compiler handles this.
Other than generated code there isn't a good reason to use a goto statement in normal code - it makes the code harder to understand and as a result more error-prone. On the other hand using goto statements in generated code like this can simplify the generation process and is normally fine because nobody is going to read (or modify) the generated code and there is no chance of mistakes being made because a machine is doing the writing.
See Go-to statement considered harmful for an argument against goto as well as a classic piece of programming history.
I don't remember ever using goto. But maybe it improves the intent of a forever loop that you really never want to exit (no break, but you can still return or throw):
forever: {
// ...
goto forever;
}
Then again, a simple while (true) should suffice...
Also, you could use in a situation where you want the first iteration of a loop to start in the middle of the loop: look here for an example.
goto is great for breaking out of many loops where break would not work well (say upon error conditions), and as Kragen said goto is used by the compiler to generate switch statements and some other things as well.
The processor implements at least one jump instruction and I'm sure lots of statements use those in thier implementation or interpretation.
One of the good things about using a 3rd or 4th generation langauge is that these physical details are abstracted away from us. Whilst we should be mindful of the law of leaky abstraction I think that we should also use our tools as they are intended (sorry). If I were writing code and a goto seemed like a good idea, it would be time to refactor. The purpose of a structured language is to avoid these "jumps" and to create a logical flow in our engineering.
I should avoid the use of break but I can't overlook the performance benefit. However, if I have nested loops that mutually need to break it is time to refactor.
If anybody can propose a use of goto that seems better than refactoring I will gladly withdraw my answer.
I hope I'm not guilty of rushing to the "bike shed" here. Like Kragen says, whats good enough for Dijkstra is good enough for me.
Goto is never better. And continue, break (except in switch/case), (multiple) return, and throw should also be kept to the barest minimum. You never want to escape from the middle of nest loops. You always want the loop control statements have all the loop control. Indenting has information, and all these statement throw that information away. You might as well take out all the indenting.

The best way to conditionally execute a function?

Yes, I know the wording is hard to understand, but this is something that bugs me a lot. On a recent project, I have a function that recurses, and there are a number of conditions that would cause it to stop recursing (at the moment three). Which of the situations would be optional? (I.E. best performance or easiest maintenance).
1) Conditional return:
void myRecursingFunction (int i, int j){
if (conditionThatWouldStopRecursing) return;
if (anotherConditionThatWouldStopRecursing) return;
if (thirdConditionThatWouldStopRecursing) return;
doSomeCodeHere();
myRecursingFunction(i + 1, j);
myRecursingFunction(i, j + 1);
}
2) Wrap the whole thing in an if statement
void myRecursingFunction (int i, int j){
if (
!conditionThatWouldStopRecursing &&
!anotherConditionThatWouldStopRecursing &&
!thirdConditionThatWouldStopRecursing
){
doSomeCodeHere();
myRecursingFunction(i + 1, j);
myRecursingFunction(i, j + 1);
}
}
3) You're doing it wrong noob, no sane algorithm would ever use recursion.
Both of those approaches should result in the same IL code behind the scenes since they are equivalent boolean expressions. Note that each termination condition will be evaluated in the order you write it (since the compiler can't tell which is most likely), so you will want to put the most common termination condition first.
Even though structured programming dictates the second approach is better, personally I prefer to code return conditions as a separate block at the top of the recursive method. I find that easier to read and follow (though I am not a fan of returns in random areas of the method body).
I would opt for the first solution, since this makes it perfectly clear what the conditions are to stop the recursion.
It is more readable and more maintainable imho.
If it's something that needs to be fast, I'd recommend hitting the most common case as quickly as possible (i.e. put the base case at the end because you'll only hit it once). Also think about putting a base case-1 before the recursing clause (i.e. perform the test before you call the function again rather than check it on entry to the subsequent call) if that will make a difference.
And, with all things, don't optimise unless it's a problem. I'd go for clarity first.
I like the variant 1 better...
It is much easier to read then variant 2. Here you have to understand 3 negations and chain them all together with and. I know its not "hard", but it takes much longer then glancing on variant 1
My vote is for option #1 as well. It looks clearer to me.

Categories