-1

If you are forced to simplify C# keywords that can be used for looping, choose only one you want to preserve.

  • for
  • do-while
  • while
  • goto-label-if
  • foreach

Is there any performance consideration regarding your decision?

Actually I don't know the internal mechanism of them, so here I want interview those of you know the details. However, someone already closed it. So sad!

Second Person Shooter
  • 14,188
  • 21
  • 90
  • 165

4 Answers4

6

goto-label-if is not actually looping. And you missed foreach.

CS theory states, that you only need while to express everything else (even conditional statements), so I'll preserve it. If you were to invent truly minimal imperative programming language, subroutine calls and while loop will suffice.

Anton Gogolev
  • 113,561
  • 39
  • 200
  • 288
  • Thanks. I will edit and add foreach. – Second Person Shooter Jul 30 '10 at 13:27
  • You may not want to hear this but they are talking about jumps not loops. – Matthew Whited Jul 30 '10 at 13:44
  • @Matthew Sorry? Jumps require `goto`, which makes program using it not quite structured. – Anton Gogolev Jul 30 '10 at 13:47
  • 1
    The only way a computer can change flow control is with a `jump`. If you look at the list of opcodes on your CPU you will not find a `while` opcode. If you notice they are referring to `label` targets. Those are the destination of a `jump`. All jumps are either `if` or `goto`. – Matthew Whited Jul 30 '10 at 13:54
  • @Matthew Whited. goto-label-if is the most efficient one? It is serious question. – Second Person Shooter Jul 30 '10 at 13:56
  • @xport, see the update to my answer. – Matthew Whited Jul 30 '10 at 14:00
  • @Matthew Agreed. But we're talking high-level programming languages here, and you'll either need `goto` and `if`, or only `while` to express all other constructs. – Anton Gogolev Jul 30 '10 at 14:03
  • Follow the first link to my other answer. You will see while, for, foreach, and goto all being used interchangeably. There are things they each do that can be done with the others. As stated below `for` can also replace all other loops. And `foreach` can replace other loops if you build an IEnumerable iterator. – Matthew Whited Jul 30 '10 at 14:07
  • 2
    You could also use 'if/recursion' you really want. This is how the tail call/pattern matching stuff works in F#. – Matthew Whited Jul 30 '10 at 14:08
  • Computer science also says that any loop can be written using recursion. The OP didn't sound interested in removing method calls, so that would still be possible, and so I'd remove `while`, too. – Ken Jul 30 '10 at 14:11
  • @Matthew, recursion needs function or procedure, and it is a building block that anyone does not want to remove I think. If I add it in the list, I put all of you in unfair position, right? – Second Person Shooter Jul 30 '10 at 15:42
  • @xport, not really. The CPU does not know what a method is. It only knows branches for flow control. Long before we had methods we had `goto/if` ... which is why methods were created. Jumping from `line 100` to `line 2078` was a mess. Some other point you could just back to before 100 or between the two values and have no good way of being able to tell were you were in your applications. That is why `goto` is considered evil. The thing is `goto` isn't typically used that way in newer languages. (And most people avoid it like the plague.) – Matthew Whited Jul 30 '10 at 16:22
5

I would keep goto-label-if. That is what the compiler turns everything into anyway. The most basic form of flow control is conditional branching and that is done with the branch/jump opcodes.

I have examples of loop conversions on the answer to another question.

... this C# code ...

static void @ifgoto(bool input)
{
    label:
        if (input)
            goto label;
}    
static void @while(bool input)
{
    while (input) ;
}
static void @for(bool input)
{
    for (; input; ) ;
}

... Compiles to this ...

.method private hidebysig static void ifgoto(bool input) cil managed
{
    .maxstack 8
    L_0000: ldarg.0 
    L_0001: brtrue.s L_0000
    L_0003: ret 
}
.method private hidebysig static void while(bool input) cil managed
{
    .maxstack 8
    L_0000: ldarg.0 
    L_0001: brtrue.s L_0000
    L_0003: ret 
}
.method private hidebysig static void for(bool input) cil managed
{
    .maxstack 8
    L_0000: ldarg.0 
    L_0001: brtrue.s L_0000
    L_0003: ret 
}

.. To explain this more ...

// load input
L_0000: ldarg.0 
// if input is true branch to L_000
L_0001: brtrue.s L_0000
// else return
L_0003: ret 
Community
  • 1
  • 1
Matthew Whited
  • 22,160
  • 4
  • 52
  • 69
4

While. Everything else can be emulated in a while loop.

I'd be sad, because i love my for loops :-(

Caladain
  • 4,801
  • 22
  • 24
1

I would leave for loop - you can omit some part of this loop and simulate other loops. And in the same time you will get more powerful loop if you'll use all parts.

DixonD
  • 6,557
  • 5
  • 31
  • 52