4 ms·
I never said "should". Really. All I said was descriptive not normative. I explicitly gave examples where trade-offs could shake out various ways. My strong
by cb321 4y ago
I never said "should". Really. All I said was descriptive not normative. I explicitly gave examples where trade-offs could shake out various ways. My strongest positive claim in this whole subthread might be "lack of common use is all that is needed for the benefits (as long as the use is easily identified by either humans, compilers, or both)." I can re-qualify that as "most benefits" if you insist. You use qualified "maybe they're right" language yourself. I don't think we're even disagreeing on the only claim I made.
In the interests of clarity, when I said "available but discouraged", I meant to refer to what you are calling "completely defanged gotos". This is the real origin of our cross-talk (and maybe any you have with others). Others do not use the term "local structured control flow" for local goto - in fact I've never heard that before. You also let "defanged" do too much work. "local goto" is by no means universally considered harmless just because it not "as bad as FLOWMATIC". Local goto was very much in Dijkstra's 1968 _Goto Considered Harmful_, for example - the OG _Harmful_ article. (FWIW, Dikjstra's earlier 1965 work proposed structured concurrency notation with "parbegin .. parend" extensions to Algol 60.) I know people that hate "return" & "break" as well for being unstructured jumps. Human language is cooperative - you may need to adjust how you discuss local gotos.
My "largely tracks" history was intentionally a rough thing. I know (local) goto statements are becoming less common, but they're not quite like punch card column rules in Fortran77. D is a recent late 90s language that did. [1] V is brand new and it has it. [2] I'm sure there are many modern examples..and more still that can cobble it together like pygoto. Herculean lengths are usually not undertaken to block a pygoto/longjmp.
Since you say longjmp is "far less powerful", I suspect you have a misimpression. You can change whatever program counter is in the jump buffer and go to any (executable) address in your virtual memory that can handle the transition. One of the other things in the the jump buffer is the stack pointer. Bad ideas for most can be useful in more expert hands. E.g., people built green threads libs around longjmp before SMP/later multi-core. [3] With many stacks. Any "yield point" anywhere in a tangle of global cross-green thread control flow could become a valid jump-back target. Some early JVMs used this, too, IIRC. I don't see this as particularly less powerful than FLOWMATIC's jumps. It kind of seems more powerful to me, but power can be hard to quantify. In context, it was also defined well enough to provide cooperative multi-threading for many users. That gnu lib is still "available" to use in C++ and probably many other things in 2022. Any "modern" language with a C backend or maybe just C FFI can also probably call longjmp. Sure, maybe not desirable. I'm not really advocating anything except maybe clarity of argument/language and awareness of properties.
Sorry..I do not know/track Rust well enough to use examples from its historical twists & turns. "Retain hairy low-level, but provide nicer high-level things" is a really common layering and all this "keep the go statement" subthread was about, IMO.. There are also warnings not only errors. Such layering is probably elsewhere in Rust, but I do not know and declare no "should". Difficulty of writing "while" or function call stacks/whatever in FLOWMATIC is simply not relevant to such highly prog.lang-and-feature-specific questions, since various other kinds of abstraction power have also increased since FLOWMATIC.
[1] https://dlang.org/spec/statement.html#goto-statement https://dlang.org/spec/statement.html#goto-statement
[2] https://github.com/vlang/v/blob/master/doc/docs.md#goto https://github.com/vlang/v/blob/master/doc/docs.md#goto
[3] https://www.gnu.org/software/pth/pth-manual.html https://www.gnu.org/software/pth/pth-manual.html
- tialaramex 4y ago> lack of common use is all that is needed for the benefits This is already wrong though. To deliver the benefits modern languages abolished the go-to feature, it's gone as the article explains and as Dijkstra anticipated. Early on in his letter Dijkstra observes that with procedures the use of a textual index as go-to's destination won't work. I used the phrase "local structured control flow" to emphasise that the defanged goto in a language like C++, unlike this go-to idea, isn't just a jump, the compiler is going to emit all the extra work needed to alter control flow here, just as it would for break or return. > Human language is cooperative I have tried very hard to refer everywhere to the idea Dijkstra is talking about as go-to rather than goto for exactly this reason. The article takes pains to explain the distinction too. Co-operation is not one sided. You cite D, which inherits the defanged goto from C but further constrains it (in D the goto can't cross an initialisation, so D's compiler needn't handle that), and then you cite V, a language whose main recent claim to fame is that it can take the game Doom written in C, transpile it to V, and then transpile that back to C, it's not a surprise to find V has lots of C warts preserved exactly as is to deliver this capability. > cobble it together like pygoto Pygoto is a cute hack, but it is not actually the go-to feature. Here's how pygoto "works": It takes your entire program, it snips off the lines before the one you want to "go to" and then it asks the Python interpreter to execute the resulting text with your current global state and exits with any resulting return code. This is why, as I already mentioned, it runs into a recursion limit when you write a program which goes back on itself, if you actually have go-to then this is merely an infinite loop, but Python doesn't, so hence the recursion. > You can change whatever program counter is in the jump buffer and go to any (executable) address in your virtual memory that can handle the transition. The longjmp feature that's actually supported is far less powerful as I explained. What you're doing here is relying on implementation details as if they were features from the language or supplied library. There's no practical difference between this strategy and just writing inline assembler to do the jump, in a complicated program it probably just won't work for a variety of reasons and nobody is interested in helping you figure out why. > Retain hairy low-level, but provide nicer high-level things ... provision of the "hairy low-level" in this case makes the nicer high-level things harder to use effectively. That's what the article is explaining. Provision of this capability is harmful, which gets us right back to Dijkstra's letter.