Notes on structured concurrency, or: Go statement considered harmful

This page summarizes the projects mentioned and recommended in the original post on

Our great sponsors
  • Scout APM - Less time debugging, more time building
  • SonarQube - Static code analysis for 29 languages.
  • SaaSHub - Software Alternatives and Reviews
  • ideas4

    An Additional 100 Ideas for Computing

    I don't see the link between golangs go statement and goto except they cause a fork in control paths. Go's go statement is not bad.

    I wrote a userspace M:N scheduler which multiplexes N lightweight threads onto M kernel threads. It currently preempts lightweight threads and tight loops round robin fashion but I could implement channels between lightweight threads and implement CSP.

    I created a construct for writing scalable systems concurrently called Crossmerge. It allows blocking synchronous code to be intermingled with while (true) loops and still make progress and join as a nursery does. There is a logical link and orthogonality between blocking and non-blocking and sometimes you need both in the same program.

  • tomb

    The tomb package helps with clean goroutine termination in the Go language.

  • Scout APM

    Less time debugging, more time building. Scout APM allows you to find and fix performance issues with no hassle. Now with error monitoring and external services monitoring, Scout is a developer's best friend when it comes to application development.

  • v

    Simple, fast, safe, compiled language for developing maintainable software. Compiles itself in <1s with zero library dependencies. Supports automatic C => V translation.

    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.. 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.




  • trio

    Trio – a friendly Python library for async concurrency and I/O

NOTE: The number of mentions on this list indicates mentions on common posts plus user suggested alternatives. Hence, a higher number means a more popular project.

Suggest a related project

Related posts