views:

196

answers:

4

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!

+4  A: 

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

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

Caladain
+6  A: 

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
Thanks. I will edit and add foreach.
xport
You may not want to hear this but they are talking about jumps not loops.
Matthew Whited
@Matthew Sorry? Jumps require `goto`, which makes program using it not quite structured.
Anton Gogolev
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
@Matthew Whited. goto-label-if is the most efficient one? It is serious question.
xport
@xport, see the update to my answer.
Matthew Whited
@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
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
You could also use 'if/recursion' you really want. This is how the tail call/pattern matching stuff works in F#.
Matthew Whited
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
@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?
xport
@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
+5  A: 

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 
Matthew Whited
Thanks down voter... care to comment on why you disagree?
Matthew Whited
+1 - cause it's definitely the most powerful one...
milan1612
Very useful demonstration.
xport
+1  A: 

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