31 ms·
I love all those "goto" disguised as any kind of flow controls. Because goto is devil, but give it another name and another smell and, voilà!, it becomes beauti
by woliveirajr 9y ago
I love all those "goto" disguised as any kind of flow controls. Because goto is devil, but give it another name and another smell and, voilà!, it becomes beautiful.
- Symmetry 9y agoAt a hardware level all control flow is made up of gotos. But by writing them as 'for' or 'break' or 'if' in our programs we make them easier to read by letting the reader know that the jump is restricted in certain ways.
- nickpsecurity 9y agoNah, hardware is more like dataflow or flow-based programming. Maybe functional programming, too. Goto is jumping to arbitrary, imperative code in RAM with an address and no regard for current state. There's possibly something in hardware like it but default stuff I saw in books were more like FSM model focused on data flows.
- Symmetry 9y agoYou're right that I should have said "At the level of the software as understood by the hardware" or something instead.
- woliveirajr 9y agoYes, I know :) . Having learnt to program some microprocessors, I love how everything is evaluated in terms of jump-if-zero, jump-if-not-zero. Well, even some cracks to copy-protection from older games (dating myself here) was just a single change from a hex 74 to a hex 75 somewhere in the code. And, sometimes, even in small programs, knowing where you are after some jumps is a messy thing. I just don't have all that rant against jumps (or goto's). I know where they live, what they eat, when they are useful and when are not. :)
- sigjuice 9y agoI encountered one of these beautiful things you mention not too long ago. void foo() { do { for (...) { if (...) { break; } } if (...) { ... if (...) { ... break; } } /* even more nested loops and conditionals with break sprinkled all over */ } while (0); ... } PS: IMHO this code goes too far with the "goto considered harmful" philosophy. The "while (0)" is serving the purpose of a label. An explicit label instead would be more readable, IMHO.
- erikpukinskis 9y agoSmells bad, but could legitimately be the correct structure. Depends on the problem and performance constraints. If you have a lot of conditionals and it's too expensive to run them all, nested ifs are correct. If you need to break from conditions arising from a multiple indexes, then nested loops are correct. Dogma has no place in coding. Best practices give you a sense of smell. They don't tell you how to factor.
- openasocket 9y agoYou would never use nested if statements for performance reasons. The conditions in any modern language will short circuit, which will give the equivalent behavior as manually making nested loops. Depending on the circumstances it might be more readable, but never more performant.
- taneq 9y agoNested if-statements lets you avoid re-evaluating the conditions between if-statements. Short-circuit evaluation only partially addresses that. It can be cleaner to cache the conditions in a few flags if you want to do it that way, though. I'm not saying deeply nested conditionals are pretty, just that there are some cases where they're quicker. (Of course, if you're scraping the bottom of the barrel for that kind of speedup then chances are, there are algorithmic improvements that will yield orders of magnitude more gains.)
- lmkg 9y agoYes. Because giving it a different name addresses the problem with goto. The problem with goto is that it is opaque. It has no structure, it has no constraints, and it communicates no intent. It says "execute the code behind this label," and gives no clue what the code is or what it does. But if you give goto a different name that reflects how you're using it, that solves the problem! If your goto is named "break" and it occurs inside a loop, that tells you what the goto is trying to achieve. It tells you at a glance what code you expect to find when you jump, and its relationship to the other code in the program. In short, it communicates intent. The same is true when the name is "continue" or "throw": you know where in the program that goto leads and what sort of code you expect to find when you go there. You don't need to read it to find out. And if you do read it, you have a better idea of whether it's right or not. (Also note that criticism of goto applies a lot more to historical gotos, whose argument was an arbitrary memory address. Modern gotos aren't nearly as bad because they generally take a label rather than a number, and because their jump targets are often restricted to the immediate lexical environment.)
- chriswarbo 9y ago> The same is true when the name is "continue" or "throw": you know where in the program that goto leads > Modern gotos aren't nearly as bad because they generally take a label rather than a number, and because their jump targets are often restricted to the immediate lexical environment. That doesn't actually apply for your examples of "continue" or "throw" though. "continue" has no label, numeric or symbolic; its target is implicit from the lexical scope. "throw" has a sort of label (the type/class of the given value/exception), but its target is determined by the dynamic environment. Given a function like: function foo() { throw Bar; } There is nothing in the lexical environment (i.e. the blocks within which it is written) that tells us where this will jump to. That information depends on what the stack looks like at the call site, which may be written by someone else, on the other side of the world, 20 years from now.
- lmkg 9y agoI apologize if I wasn't clear, I didn't mean to say that continue/throw are similar to modern gotos. Renamed gotos such as continue, break, and throw address the primary drawbacks of raw gotos. Unrelatedly, the gotos that one is likely to encounter in a modern-ish language like C or Common Lisp don't have all of those drawbacks anyways. My purpose was not to draw a comparison, merely to add some additional context for Dijkstra's original rants that may explain why the hard-line stance he took at the time makes a little less sense today.