Thread overview | |||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
October 01, 2013 goto a no-go? | ||||
---|---|---|---|---|
| ||||
Just a short question. Usually goto statements are frowned upon as being bad programming style (in textbooks at least). D has it (thankfully) and I've used it, albeit sparingly. Sometimes goto is simply the best and most efficient solution within a code block (to avoid code duplication, unnecessary checks or redirecting to yet another function blah blah). Is it ok or even necessary to use goto in D? Or does the compiler recognize _obvious_ cases and generate code accordingly? For example would it turn something like this // ... if (word.length == 1) { // format output return output; } else if (word.length > 1) { // do some additional processing // format output return output; } into // ... if (word.length == 1) goto FormatOutput; // if word.length > 1, some extra work has to be done // initialize some variables, parse, do some processing etc. FormatOutput: // ..... return output; |
October 01, 2013 Re: goto a no-go? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris | > // ... > if (word.length == 1) goto FormatOutput; > > // if word.length > 1, some extra work has to be done > // initialize some variables, parse, do some processing etc. > > FormatOutput: > // ..... > > return output; Have never felt need to use `goto` since got familiar with `scope(something)` : http://dpaste.dzfl.pl/ca40b3b6 ;) |
October 01, 2013 Re: goto a no-go? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On Tuesday, 1 October 2013 at 11:26:54 UTC, Dicebot wrote:
>> // ...
>> if (word.length == 1) goto FormatOutput;
>>
>> // if word.length > 1, some extra work has to be done
>> // initialize some variables, parse, do some processing etc.
>>
>> FormatOutput:
>> // .....
>>
>> return output;
>
> Have never felt need to use `goto` since got familiar with `scope(something)` : http://dpaste.dzfl.pl/ca40b3b6
>
> ;)
Thanks, this is what I was looking for, a more elegant solution. I was going through some old code and saw the odd goto statement. scope() shows of course that some sort of goto mechanism is pretty handy (no matter what the textbooks say).
|
October 01, 2013 Re: goto a no-go? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris | On Tuesday, 1 October 2013 at 11:22:12 UTC, Chris wrote: > Just a short question. Usually goto statements are frowned upon as being bad programming style (in textbooks at least). D has it (thankfully) and I've used it, albeit sparingly. Sometimes goto is simply the best and most efficient solution within a code block (to avoid code duplication, unnecessary checks or redirecting to yet another function blah blah). Is it ok or even necessary to use goto in D? Or does the compiler recognize _obvious_ cases and generate code accordingly? For example would it turn something like this > > // ... > if (word.length == 1) { > // format output > return output; > } else if (word.length > 1) { > // do some additional processing > // format output > return output; > } > > into > > // ... > if (word.length == 1) goto FormatOutput; > > // if word.length > 1, some extra work has to be done > // initialize some variables, parse, do some processing etc. > > FormatOutput: > // ..... > > return output; How is that transformation an optimization or improvement? Substituting "return output" for "goto FormatOutput" is not better. So, I assume "// format output" is the code duplication you want to remove? Well, your example should also work like this: if (word.length > 1) { // do some additional processing } // format output return output; Regarding goto and D, scope guards [0] are good for removing gotos, because the cleanup-after-error code can be moved. [0] http://dlang.org/statement.html#ScopeGuardStatement |
October 01, 2013 Re: goto a no-go? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Attachments:
| On 1 October 2013 21:22, Chris <wendlec@tcd.ie> wrote:
> Just a short question. Usually goto statements are frowned upon as being bad programming style (in textbooks at least). D has it (thankfully) and I've used it, albeit sparingly. Sometimes goto is simply the best and most efficient solution within a code block (to avoid code duplication, unnecessary checks or redirecting to yet another function blah blah). Is it ok or even necessary to use goto in D? Or does the compiler recognize _obvious_ cases and generate code accordingly? For example would it turn something like this
>
> // ...
> if (word.length == 1) {
> // format output
> return output;
> } else if (word.length > 1) {
> // do some additional processing
> // format output
> return output;
> }
>
> into
>
> // ...
> if (word.length == 1) goto FormatOutput;
>
> // if word.length > 1, some extra work has to be done
> // initialize some variables, parse, do some processing etc.
>
> FormatOutput:
> // .....
>
> return output;
>
Well, obviously that should be rewritten:
if (word.length > 1)
{
// additional processing
}
// format output
return output;
Note: there's an un-handled case in your example, but I'll ignore that. Anyway, goto is supported. Walter likes it. I use it from time to time. I'd say 90% of the time I find goto useful is when I need to bail from nested loops. I've often wondered if something like break(2) would be a more elegant solution to the breaking out of nested loops problem.
But in direct answer to your question, I think you'll find modern optimisers are smart enough to make the optimisation you are looking for. I haven't tested that precise case, but I've definitely expected the optimiser to do the right thing in similar cases, and it does. I rarely write code that requires me to have faith in any optimiser though.
|
October 01, 2013 Re: goto a no-go? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On Tuesday, 1 October 2013 at 11:40:35 UTC, Manu wrote:
> I'd say 90% of the time I find goto useful is when I need to bail from
> nested loops. I've often wondered if something like break(2) would be a
> more elegant solution to the breaking out of nested loops problem.
labeled statements to the rescue!
outer: foreach(i; 0..10)
{
foreach(j; 0..10)
{
break outer;
}
}
|
October 01, 2013 Re: goto a no-go? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris | On Tuesday, 1 October 2013 at 11:22:12 UTC, Chris wrote:
> Is it ok or even necessary to use goto in D?
It's best viewed as a compatibility or micro-optimization feature. For structuring code, D obsoletes goto with nested functions, scope statements and labelled break and continue.
Most experienced D programmers use scope statements and labelled break/continue to replace goto with great effect, but sometimes the same programmers can still be seen using goto when a nested function would really have solved the issue more structurally, so I recommend experimenting with nested functions if they are unfamiliar to you.
|
October 01, 2013 Re: goto a no-go? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris | On Tuesday, 1 October 2013 at 11:35:35 UTC, Chris wrote:
> Thanks, this is what I was looking for, a more elegant solution. I was going through some old code and saw the odd goto statement. scope() shows of course that some sort of goto mechanism is pretty handy (no matter what the textbooks say).
goto is not avoided because of functionality it enables but because of unhygienic way it is implemented. scope guards offer part of that functionality in much more clean and safe way and there is nothing wrong about using them.
|
October 01, 2013 Re: goto a no-go? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris | On 1-10-2013 13:22, Chris wrote: >Is it ok or even necessary to use goto in D? I doubt it's necessary but it can be useful sometimes. In the Markov algorithm at Rosetta code I used it to restart a loop, including reinitializing a variable. I'm sure it could have been done without goto but it was convenient. http://rosettacode.org/wiki/Markov_Algorithm#D |
October 01, 2013 Re: goto a no-go? | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | On Tuesday, 1 October 2013 at 11:47:37 UTC, John Colvin wrote:
> On Tuesday, 1 October 2013 at 11:40:35 UTC, Manu wrote:
>> I'd say 90% of the time I find goto useful is when I need to bail from
>> nested loops. I've often wondered if something like break(2) would be a
>> more elegant solution to the breaking out of nested loops problem.
>
> labeled statements to the rescue!
>
> outer: foreach(i; 0..10)
> {
> foreach(j; 0..10)
> {
> break outer;
> }
> }
break outer; Obsoletes one of my "only" use cases where before, I would have used a goto instead:
foreach(i; 0..10)
{
foreach(j; 0..10)
{
goto double_break;
}
}
double_break: {}
It's awesome.
Too bad you can't break from an arbitrary block though. It can help avoiding the dreaded "if(if(if(if(...))))" pattern, as well as the "bool didYouDoIt" pattern. I still have to use my "goto after_block" pattern :/
//----
//Search and deal with a specific condition
//While doing something special if the condition is not found.
{
if (some_condition) goto block_end; //No need to do anything
if (some_other_condition) goto block_end; //No need to do anything
if (some_third_condition) goto block_end; //No need to do anything
for (...)
{
for (...)
{
if (...)
{
do_processing();
goto block_end; //We found what we wanted.
}
}
}
do_code_for_not_found_here();
}
done_processing: {}
//Keep going here
//----
I guess I can always use the "do{}while(false);" pattern, but I actually find it *more* confusing (IMO)
|
Copyright © 1999-2021 by the D Language Foundation