digitalmars.D - 'goto', as an indicator of good language
- AnimusPEXUS (10/10) Sep 08 2022 There was a discussion sometime ago in a Russian Dlang Telegram
- Steven Schveighoffer (9/20) Sep 08 2022 goto in D is sane. You cannot skip initializations. You cannot skip
- Walter Bright (4/4) Sep 08 2022 To be fair, nested functions along with function inlining has eliminated...
- JN (4/8) Sep 09 2022 I find it surprising that no language added something like "break
- jmh530 (19/28) Sep 09 2022 D can break on labels, which is even more powerful than that. To
- Nick Treleaven (60/64) Sep 09 2022 Yeah, there's this code from dmd/dsymbolsem.d:
- Paul Backus (11/33) Sep 09 2022 I think maybe a more intuitive keyword for this would be `do`:
- Nick Treleaven (4/17) Sep 09 2022 So continue would do the same as break? Bit weird.
- Steven Schveighoffer (30/53) Sep 09 2022 Instead of switch, you can use:
- Nick Treleaven (8/38) Sep 09 2022 Not the same, continue applies to the do then, not an outer loop.
- Steven Schveighoffer (11/30) Sep 09 2022 If we are talking about wrapping existing code that might contain a
- Nick Treleaven (7/38) Sep 09 2022 If you know there's no break but there is a continue, you don't
- Steven Schveighoffer (9/33) Sep 09 2022 If the closing brace is close at hand, then the appropriate label would
- Nick Treleaven (14/33) Sep 10 2022 That's where bugs hide.
- IGotD- (15/25) Sep 08 2022 Does this apply to all languages or only "systems languages"?
- AnimusPEXUS (3/8) Sep 08 2022 Go supports too
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (4/8) Sep 09 2022 Exceptions?
- Dukc (15/25) Sep 08 2022 My personal attitude to `goto` is that it's overhated. While it's
- H. S. Teoh (32/55) Sep 08 2022 [...]
- Dukc (13/21) Sep 08 2022 Well if I really wanted to I could do it in 60s style by putting
- H. S. Teoh (55/77) Sep 08 2022 Still can't get around variable initializations / destructions. ;-)
- Walter Bright (3/3) Sep 08 2022 goto can be handy to avoid needing to refactor a bunch of code when fixi...
- max haughton (3/6) Sep 08 2022 It almost never does though, let's be realistic.
- H. S. Teoh (32/39) Sep 08 2022 IME, typically code stinks come about this way:
- Walter Bright (2/4) Sep 08 2022 Quite a few of my PRs are refactorings.
- max haughton (21/25) Sep 09 2022 You are much better than most in this regard but my point is that
- JG (3/6) Sep 10 2022 Just to be sure could you please give a small example.
- user1234 (7/18) Sep 09 2022 This is what Zig did see
There was a discussion sometime ago in a Russian Dlang Telegram chat about 'goto' keyword. And there was some empiric theory, stating 'all good languages support goto statement'. Nor Rust, nor Carbon, nor Zig will never going to overcome D or C++ because of this. Language should give possibilities, not take them away. And in some cases, goto able to make code more readable, more sane and more understandable. Also, goto is much safer in language with GC. [corresponding section in wikipedia](https://en.wikipedia.org/wiki/Goto#Criticism)
Sep 08 2022
On 9/8/22 12:33 PM, AnimusPEXUS wrote:There was a discussion sometime ago in a Russian Dlang Telegram chat about 'goto' keyword. And there was some empiric theory, stating 'all good languages support goto statement'. Nor Rust, nor Carbon, nor Zig will never going to overcome D or C++ because of this. Language should give possibilities, not take them away. And in some cases, goto able to make code more readable, more sane and more understandable. Also, goto is much safer in language with GC. [corresponding section in wikipedia](https://en.wikipedia.org/wiki/Goto#Criticism)goto in D is sane. You cannot skip initializations. You cannot skip variable declarations. You can't jump into other functions. You can't jump out of or into certain things (e.g. a finally clause). Loops and if/switch statements are glorified gotos. If you need something different, goto can make code much much easier to read/write/understand rather than trying to shoehorn it into one of these other constructs. -Steve
Sep 08 2022
To be fair, nested functions along with function inlining has eliminated many of the reasons that I use gotos. Another reason for gotos is for ways of exiting loops without having to set flags that later control the flow.
Sep 08 2022
On Thursday, 8 September 2022 at 22:47:33 UTC, Walter Bright wrote:To be fair, nested functions along with function inlining has eliminated many of the reasons that I use gotos. Another reason for gotos is for ways of exiting loops without having to set flags that later control the flow.I find it surprising that no language added something like "break all;" instruction to exit all loops.
Sep 09 2022
On Friday, 9 September 2022 at 09:30:21 UTC, JN wrote:On Thursday, 8 September 2022 at 22:47:33 UTC, Walter Bright wrote:D can break on labels, which is even more powerful than that. To be honest, I don't recall ever using it in my own code, but it works. ```d import core.stdc.stdio: printf; void main() { outer: for (size_t i = 0; i < 4; i++) { for (size_t j = 0; j < 4; j++) { if (i * j > 4) { break outer; } printf("i = %lu, j = %lu\n", i, j); } printf("i = %lu\n", i); } } ```To be fair, nested functions along with function inlining has eliminated many of the reasons that I use gotos. Another reason for gotos is for ways of exiting loops without having to set flags that later control the flow.I find it surprising that no language added something like "break all;" instruction to exit all loops.
Sep 09 2022
On Thursday, 8 September 2022 at 22:47:33 UTC, Walter Bright wrote:To be fair, nested functions along with function inlining has eliminated many of the reasons that I use gotos. Another reason for gotos is for ways of exiting loops without having to set flags that later control the flow.Yeah, there's this code from dmd/dsymbolsem.d: ```d if (FuncDeclaration func = sc.parent.isFuncDeclaration()) { tm.symtab = func.localsymtab; if (tm.symtab) { // Inside template constraint, symtab is not set yet. goto L1; } } else { tm.symtab = sc.parent.isScopeDsymbol().symtab; L1: assert(tm.symtab); tm.ident = Identifier.generateId(s, tm.symtab.length + 1); tm.symtab.insert(tm); } ``` You can write it as: ```d (){ if (FuncDeclaration func = sc.parent.isFuncDeclaration()) { tm.symtab = func.localsymtab; if (!tm.symtab) return; // Inside template constraint, symtab is not set yet. } else tm.symtab = sc.parent.isScopeDsymbol().symtab; //L1: assert(tm.symtab); tm.ident = Identifier.generateId(s, tm.symtab.length + 1); tm.symtab.insert(tm); }(); ``` I'd prefer to write it as: ```d switch { if (FuncDeclaration func = sc.parent.isFuncDeclaration()) { tm.symtab = func.localsymtab; if (!tm.symtab) break; // Inside template constraint, symtab is not set yet. } else tm.symtab = sc.parent.isScopeDsymbol().symtab; //L1: assert(tm.symtab); tm.ident = Identifier.generateId(s, tm.symtab.length + 1); tm.symtab.insert(tm); } ``` Where `switch` works like `switch(0) default:` today. Using the function literal call means you can't return from the containing function, which may be needed.
Sep 09 2022
On Friday, 9 September 2022 at 14:03:57 UTC, Nick Treleaven wrote:I'd prefer to write it as: ```d switch { if (FuncDeclaration func = sc.parent.isFuncDeclaration()) { tm.symtab = func.localsymtab; if (!tm.symtab) break; // Inside template constraint, symtab is not set yet. } else tm.symtab = sc.parent.isScopeDsymbol().symtab; //L1: assert(tm.symtab); tm.ident = Identifier.generateId(s, tm.symtab.length + 1); tm.symtab.insert(tm); } ``` Where `switch` works like `switch(0) default:` today.I think maybe a more intuitive keyword for this would be `do`: ```d do { // ... if (whatever) break; // ... } ``` ...which would work like `do { ... } while (0);` currently does.
Sep 09 2022
On Friday, 9 September 2022 at 14:18:04 UTC, Paul Backus wrote:On Friday, 9 September 2022 at 14:03:57 UTC, Nick Treleaven wrote:So continue would do the same as break? Bit weird. Also you don't know if it's a loop or not until you find the closing brace. It's better to know in advance.Where `switch` works like `switch(0) default:` today.I think maybe a more intuitive keyword for this would be `do`: ```d do { // ... if (whatever) break; // ... } ``` ...which would work like `do { ... } while (0);` currently does.
Sep 09 2022
On 9/9/22 10:03 AM, Nick Treleaven wrote:I'd prefer to write it as: ```d switch { if (FuncDeclaration func = sc.parent.isFuncDeclaration()) { tm.symtab = func.localsymtab; if (!tm.symtab) break; // Inside template constraint, symtab is not set yet. } else tm.symtab = sc.parent.isScopeDsymbol().symtab; //L1: assert(tm.symtab); tm.ident = Identifier.generateId(s, tm.symtab.length + 1); tm.symtab.insert(tm); } ``` Where `switch` works like `switch(0) default:` today. Using the function literal call means you can't return from the containing function, which may be needed.Instead of switch, you can use: ```d do { ... } while(false); ``` And then use a break inside. But honestly, all this looks like "I want to avoid goto at all costs". The original looks better to me. Another possibility that uses goto, but might be preferred, is: ```d if (FuncDeclaration func = sc.parent.isFuncDeclaration()) { tm.symtab = func.localsymtab; if (!tm.symtab) { // Inside template constraint, symtab is not set yet. goto L1; } } else { tm.symtab = sc.parent.isScopeDsymbol().symtab; } assert(tm.symtab); tm.ident = Identifier.generateId(s, tm.symtab.length + 1); tm.symtab.insert(tm); L1: ``` -Steve
Sep 09 2022
On Friday, 9 September 2022 at 14:22:51 UTC, Steven Schveighoffer wrote:Instead of switch, you can use: ```d do { ... } while(false); ``` And then use a break inside.Not the same, continue applies to the do then, not an outer loop. Also not clear until the end of the construct that it's not a loop.But honestly, all this looks like "I want to avoid goto at all costs". The original looks better to me.It's easier to reason about switch because you don't have to read the whole function looking for the matching label.Another possibility that uses goto, but might be preferred, is: ```d if (FuncDeclaration func = sc.parent.isFuncDeclaration()) { tm.symtab = func.localsymtab; if (!tm.symtab) { // Inside template constraint, symtab is not set yet. goto L1; } } else { tm.symtab = sc.parent.isScopeDsymbol().symtab; } assert(tm.symtab); tm.ident = Identifier.generateId(s, tm.symtab.length + 1); tm.symtab.insert(tm); L1: ```That's an improvement.
Sep 09 2022
On 9/9/22 11:40 AM, Nick Treleaven wrote:On Friday, 9 September 2022 at 14:22:51 UTC, Steven Schveighoffer wrote:If we are talking about wrapping existing code that might contain a continue, you need to also consider that the existing code might contain a break. In both cases, you could label the target and use a targeted continue or break statement. But again, goto is better here.Instead of switch, you can use: ```d do { ... } while(false); ``` And then use a break inside.Not the same, continue applies to the do then, not an outer loop. Also not clear until the end of the construct that it's not a loop.You don't though. Just search for it. Just like you would have to search for the matching closing brace of the switch. At least in the case of the label, you can use text search, and not have to account for nested braces. -SteveBut honestly, all this looks like "I want to avoid goto at all costs". The original looks better to me.It's easier to reason about switch because you don't have to read the whole function looking for the matching label.
Sep 09 2022
On Friday, 9 September 2022 at 15:57:45 UTC, Steven Schveighoffer wrote:On 9/9/22 11:40 AM, Nick Treleaven wrote:If you know there's no break but there is a continue, you don't have to use a label.On Friday, 9 September 2022 at 14:22:51 UTC, Steven Schveighoffer wrote:If we are talking about wrapping existing code that might contain a continue, you need to also consider that the existing code might contain a break. In both cases, you could label the target and use a targeted continue or break statement.Instead of switch, you can use: ```d do { ... } while(false); ``` And then use a break inside.Not the same, continue applies to the do then, not an outer loop. Also not clear until the end of the construct that it's not a loop.But again, goto is better here.Why would you need to stop reading the code sequentially and lookup the closing brace? With goto you need to to understand what you're looking at. That's my point.You don't though. Just search for it. Just like you would have to search for the matching closing brace of the switch. At least in the case of the label, you can use text search, and not have to account for nested braces.But honestly, all this looks like "I want to avoid goto at all costs". The original looks better to me.It's easier to reason about switch because you don't have to read the whole function looking for the matching label.
Sep 09 2022
On 9/9/22 12:31 PM, Nick Treleaven wrote:On Friday, 9 September 2022 at 15:57:45 UTC, Steven Schveighoffer wrote:So when you say "Not the same", you mean that <1% difference.On 9/9/22 11:40 AM, Nick Treleaven wrote:If you know there's no break but there is a continue, you don't have to use a label.Not the same, continue applies to the do then, not an outer loop. Also not clear until the end of the construct that it's not a loop.If we are talking about wrapping existing code that might contain a continue, you need to also consider that the existing code might contain a break. In both cases, you could label the target and use a targeted continue or break statement.If the closing brace is close at hand, then the appropriate label would be too. It will even stand out more. But you are saying "read the whole function". I'm assuming you mean that it's far away from the break/goto statement. If it's off-screen, the label wins hands-down. Using my editor I can find "L1:" much easier than I can find a specific "}" -SteveWhy would you need to stop reading the code sequentially and lookup the closing brace? With goto you need to to understand what you're looking at. That's my point.It's easier to reason about switch because you don't have to read the whole function looking for the matching label.You don't though. Just search for it. Just like you would have to search for the matching closing brace of the switch. At least in the case of the label, you can use text search, and not have to account for nested braces.
Sep 09 2022
On Friday, 9 September 2022 at 17:04:44 UTC, Steven Schveighoffer wrote:So when you say "Not the same", you mean that <1% difference.That's where bugs hide.Why do I need to stop reading the code sequentially and find the closing brace of a switch? I do not. Searching for a label *is disruptive*, even if automated, it breaks my train of thought. With goto the matching label could be inside the switch or it could be outside it, at different levels of scope. With break, you know it just jumps to the end of the switch. When I'm reading code, I'm trying to understand each statement. I can't understand a goto without knowing which scope it goes to. With break you know what scope that is. This is a key part of why we have structured programming, because you know where the code will go to when exiting a construct.If the closing brace is close at hand, then the appropriate label would be too. It will even stand out more. But you are saying "read the whole function". I'm assuming you mean that it's far away from the break/goto statement. If it's off-screen, the label wins hands-down. Using my editor I can find "L1:" much easier than I can find a specific "}"Why would you need to stop reading the code sequentially and lookup the closing brace? With goto you need to to understand what you're looking at. That's my point.It's easier to reason about switch because you don't have to read the whole function looking for the matching label.You don't though. Just search for it. Just like you would have to search for the matching closing brace of the switch. At least in the case of the label, you can use text search, and not have to account for nested braces.
Sep 10 2022
On Thursday, 8 September 2022 at 16:33:58 UTC, AnimusPEXUS wrote:There was a discussion sometime ago in a Russian Dlang Telegram chat about 'goto' keyword. And there was some empiric theory, stating 'all good languages support goto statement'. Nor Rust, nor Carbon, nor Zig will never going to overcome D or C++ because of this. Language should give possibilities, not take them away. And in some cases, goto able to make code more readable, more sane and more understandable. Also, goto is much safer in language with GC. [corresponding section in wikipedia](https://en.wikipedia.org/wiki/Goto#Criticism)Does this apply to all languages or only "systems languages"? If we look at current popular heavy lifting languages. Support goto: Objective-C Do not support goto: Python Java Swift It seems to be a bit too simplistic criteria to me. Anyway, I haven't used goto a lot in C/C++ other than in "roll back error handling". D manage to do this even better with with its scope guards. How does other languages handle "roll back error handling" (is there a better terminology for this?).
Sep 08 2022
On Thursday, 8 September 2022 at 17:04:28 UTC, IGotD- wrote:Does this apply to all languages or only "systems languages"?I think it's apply to any General-purpose languageIf we look at current popular heavy lifting languages. Support goto: Objective-CGo supports too
Sep 08 2022
On Thursday, 8 September 2022 at 17:04:28 UTC, IGotD- wrote:Anyway, I haven't used goto a lot in C/C++ other than in "roll back error handling". D manage to do this even better with with its scope guards. How does other languages handle "roll back error handling" (is there a better terminology for this?).Exceptions? Goto is useful when implementing state machines, the resulting code is often more readable.
Sep 09 2022
On Thursday, 8 September 2022 at 16:33:58 UTC, AnimusPEXUS wrote:There was a discussion sometime ago in a Russian Dlang Telegram chat about 'goto' keyword. And there was some empiric theory, stating 'all good languages support goto statement'. Nor Rust, nor Carbon, nor Zig will never going to overcome D or C++ because of this. Language should give possibilities, not take them away. And in some cases, goto able to make code more readable, more sane and more understandable. Also, goto is much safer in language with GC. [corresponding section in wikipedia](https://en.wikipedia.org/wiki/Goto#Criticism)My personal attitude to `goto` is that it's overhated. While it's true that conditional and loop statements are mostly better, an occasional `goto` is not necessarily a code smell. Also I'd be much more worried about mutable `static`/global variables and oversized functions/types than a few needless `goto`s in a module. I suspect it's bad reputation is from the times when some (non-assembly) languages did not have structured programming and everything was done with `goto`s. Going back to that sure would suck, but there's quite a difference between an occasional `goto` and replacing all your loops with it. sometimes prefer it, but when I resort to it in D I usually notice a better way shortly afterwards. I'd be slightly annoyed to live without it but could easily cope.
Sep 08 2022
On Thu, Sep 08, 2022 at 08:39:30PM +0000, Dukc via Digitalmars-d wrote:On Thursday, 8 September 2022 at 16:33:58 UTC, AnimusPEXUS wrote:[...] Also keep in mind that `goto` in modern-day languages is a very different thing from `goto` in the old days. In the old days, it was the equivalent of a `jmp` instruction in assembly language; it could literally jump *anywhere* in the program, including jump from the middle of function A into the middle of function B where B isn't even on the call stack. It would skip variable cleanups and initializations, stack adjustments, etc., and generally produce *really* unreadable code. (See, for example, GOTO in old versions of BASIC, that lets you jump to any arbitrary line in your program.) It's even more powerful (and dangerous) than C's longjmp(), because the destination of the goto doesn't even have to be on the call stack or anywhere near where the history of execution has passed. The `goto` of today's languages is a much safer, de-fanged version of the original goto. In D, for example, you cannot `goto` out of a function (or into another). The compiler also doesn't let you skip variable initializations / destructions. So it's subject to pretty much the same constraints as "structured" constructs like if, while, for, switch, etc., except it's more low-level and can do a few more things that the other constructs can't do. So yes, you can overuse `goto` in your function and make it hard to follow, but then nested if-else blocks and loops that span 5000 lines are also hard to read[1], so it's not saying very much. And today's goto is nowhere near as wild as the original `goto` in the old days. [1] I'm not making this up, I've actually seen 5000+ line functions in real-world "enterprise" code. They are one of those things you wish you never have to debug, because you just can't fully understand what they do, goto or not. T -- Always remember that you are unique. Just like everybody else. -- despair.comThere was a discussion sometime ago in a Russian Dlang Telegram chat about 'goto' keyword. And there was some empiric theory, stating 'all good languages support goto statement'. Nor Rust, nor Carbon, nor Zig will never going to overcome D or C++ because of this. Language should give possibilities, not take them away. And in some cases, goto able to make code more readable, more sane and more understandable. Also, goto is much safer in language with GC. [corresponding section in wikipedia](https://en.wikipedia.org/wiki/Goto#Criticism)My personal attitude to `goto` is that it's overhated. While it's true that conditional and loop statements are mostly better, an occasional `goto` is not necessarily a code smell. Also I'd be much more worried about mutable `static`/global variables and oversized functions/types than a few needless `goto`s in a module. I suspect it's bad reputation is from the times when some (non-assembly) languages did not have structured programming and everything was done with `goto`s. Going back to that sure would suck, but there's quite a difference between an occasional `goto` and replacing all your loops with it.
Sep 08 2022
On Thursday, 8 September 2022 at 21:03:04 UTC, H. S. Teoh wrote:The `goto` of today's languages is a much safer, de-fanged version of the original goto. In D, for example, you cannot `goto` out of a function (or into another). The compiler also doesn't let you skip variable initializations / destructions. So it's subject to pretty much the same constraints as "structured" constructs like if, while, for, switch, etc., except it's more low-level and can do a few more things that the other constructs can't do.Well if I really wanted to I could do it in 60s style by putting everything inside a giant `switch(callStack.pop)` in `main()`. "functions" would be just `goto` labels, called like this: ```D callStack.push(something); goto function; case something: ``` ...with a jump to the switch at end of each "function" body. So `goto` does technically have as long fangs as always :D. Of course, modern languages do a good job encouraging better coding habits.
Sep 08 2022
On Thu, Sep 08, 2022 at 09:30:06PM +0000, Dukc via Digitalmars-d wrote:On Thursday, 8 September 2022 at 21:03:04 UTC, H. S. Teoh wrote:Still can't get around variable initializations / destructions. ;-) Plus, if your code ever interacts with mine, it would not be able to willy-nilly goto into my function, no matter what other atrocities it's committing inside main(). In 60s style code, you'd just `lea` to get the address of the target function, perform pointer arithmetic, and `jmp` to the destination, whether or not the callee wants to be called that way or not. :-D Fortunately, such nonsense is blocked at the language level.The `goto` of today's languages is a much safer, de-fanged version of the original goto. In D, for example, you cannot `goto` out of a function (or into another). The compiler also doesn't let you skip variable initializations / destructions. So it's subject to pretty much the same constraints as "structured" constructs like if, while, for, switch, etc., except it's more low-level and can do a few more things that the other constructs can't do.Well if I really wanted to I could do it in 60s style by putting everything inside a giant `switch(callStack.pop)` in `main()`. "functions" would be just `goto` labels, called like this: ```D callStack.push(something); goto function; case something: ``` ...with a jump to the switch at end of each "function" body.So `goto` does technically have as long fangs as always :D. Of course, modern languages do a good job encouraging better coding habits.Well, that's kinda an unfair way to look at it. I mean, if I *really* wanted to write code like the above, I don't even need `goto`; it suffices to just write something like this: void main() { int state = 1; int globalVar; switch (state) { case 1: doSomething(); globalVar++; state = 5; break; case 2: doSomethingElse(); globalVar--; state = 3; break; case 3: doYetSomethingElse(); globalVar += 2; state = 6; break; case 4: blahblahblah(); globalVar -= 2; state = 1; break; case 5: andSoOn(); globalVar *= 2; state = 2; break; case 6: justForKicks(); globalVar /= 3; state = uniform(1, 7); break; } } I mean, I could write an assembly language emulator in main(), and write the worst possible random-jump-ridden, self-mutating virus code that main() would execute, but that doesn't mean D is inherently bad because it's possible to do so. T -- "Real programmers can write assembly code in any language. :-)" -- Larry Wall
Sep 08 2022
goto can be handy to avoid needing to refactor a bunch of code when fixing a problem. The refactoring can come later in its own PR.
Sep 08 2022
On Thursday, 8 September 2022 at 22:49:05 UTC, Walter Bright wrote:goto can be handy to avoid needing to refactor a bunch of code when fixing a problem. The refactoring can come later in its own PR.It almost never does though, let's be realistic.
Sep 08 2022
On Fri, Sep 09, 2022 at 12:26:44AM +0000, max haughton via Digitalmars-d wrote:On Thursday, 8 September 2022 at 22:49:05 UTC, Walter Bright wrote:IME, typically code stinks come about this way: 1) Original code is reasonably clean and well-written. 2) A critical bug is discovered 2 days before the release deadline. 3) In the mad rush to get the release out the door, Good-Hearted possible. He comforts himself, "I will clean up this messy hack code after the release." makes it out the door on time. There is celebration, and o' days to recover from the release. code, PTB walks in and hands him High Priority Project X that has to be done by last week. He gets totally occupied with Project X and forgets about cleaning up the code. 6) Meanwhile, another release deadline looms, and another bug is himself, "There's no time to figure this out, I'll just patch over the code and redo the fix properly after the release." to a different company altogether. And so layer upon layer of hacks and bandages are accumulated on top of the code, the well-intentioned cleanups never happen. Soon, so much cruft has accumulated that nobody knows how to clean it up anymore. Instead, the bugs and quirky behaviours are worked around and patched over, and customers begin relying on the quirky behaviour, further cementing it forever. T -- MACINTOSH: Most Applications Crash, If Not, The Operating System Hangsgoto can be handy to avoid needing to refactor a bunch of code when fixing a problem. The refactoring can come later in its own PR.It almost never does though, let's be realistic.
Sep 08 2022
On 9/8/2022 5:26 PM, max haughton wrote:Quite a few of my PRs are refactorings.The refactoring can come later in its own PR.It almost never does though, let's be realistic.
Sep 08 2022
On Friday, 9 September 2022 at 02:00:28 UTC, Walter Bright wrote:On 9/8/2022 5:26 PM, max haughton wrote:You are much better than most in this regard but my point is that every at some point thinks "This is the million dollar goto, I've been waiting for this moment all year" or just that one goto couldn't posssibbblyy hurt, and locally they might well be right but in my experience with the exception of tight interpreter loops I *very* rarely see truly justified uses for goto. They might look clever but they're usually a symptom of code that is to abstraction/design what goto is to structured control flow. If the code does eventually get refactored then great but especially in a professional environment where you might be more able to manage a larger refactoring, it's better to pay the refactoring cost now rather than later if at all possible. Another more subtle psychological factor against using goto is that sometimes gotos are actually worth it, fair enough, but now other people working on the code can see the goto in the corner of their eye and think they can program like it's 1999 and blame it on the goto. Replacing gotos with a void function call return is a nice pattern that D luckily makes trivial to use, for anyone reading unaware of the pattern.Quite a few of my PRs are refactorings.The refactoring can come later in its own PR.It almost never does though, let's be realistic.
Sep 09 2022
On Saturday, 10 September 2022 at 06:27:32 UTC, max haughton wrote:Replacing gotos with a void function call return is a nice pattern that D luckily makes trivial to use, for anyone reading unaware of the pattern.Just to be sure could you please give a small example.
Sep 10 2022
On Thursday, 8 September 2022 at 16:33:58 UTC, AnimusPEXUS wrote:There was a discussion sometime ago in a Russian Dlang Telegram chat about 'goto' keyword. And there was some empiric theory, stating 'all good languages support goto statement'. Nor Rust, nor Carbon, nor Zig will never going to overcome D or C++ because of this. Language should give possibilities, not take them away.This is what Zig did see https://github.com/ziglang/zig/issues/630. I think that the rationale is quite good. Goto solves *almost* no problem.And in some cases, goto able to make code more readable, more sane and more understandable. Also, goto is much safer in language with GC.That's a good point.[corresponding section in wikipedia](https://en.wikipedia.org/wiki/Goto#Criticism)See also https://wiki.c2.com/?GoodUseOfGoto
Sep 09 2022