Of course not. It also isn't original, or a "silver bullet" that I find relevant to general concurrent programming.
> I don't really understand what you mean by this.
I was trying to keep my rant a bit short, but my point is that the only practical example for a post that puts a lot of effort into complaining about a core Go construct (it's the title) does not even remotely apply to Go.
This is partly due to Go being shaped around this very core construct.
> Why exactly is branching better?
"goto" can (sometimes, as there are many valid usecases) be problematic as it can make control flow very obscure when read. "go" is extremely clear to read, and only has the concern that you don't know if a given function has created goroutines. It is of course usually described by documentation, or implicit from functionality that such thing will occur, and unlike goto, the code is extremely clear about what is going on if you read it.
Furthermore, whether a function call has created goroutines is by itself not a concern. What can be a concern would be if some types of resources that must be closed (i.e. a file) is referenced after you close it. That is not related to concurrency, but lifetimes.
By lifetimes, I do not necessarily mean Rust-style compiler-enforced lifetimes (which I like), but simply API contracts. A library may store a reference to something you pass, and may use this reference in later calls, potentially after you invalidated the reference by closing a file descriptor.
A joined execution does not even remotely solve this problem, as it is not related to concurrency. It solves a different problem, related to just managing concurrent execution.
> These are all related concepts. They are about doing different things "at the same time, ...
They are not at all. Callbacks are often used together with certain types of concurrency constructs, such as an event-loop that can call callbacks upon various events. In JS, for example, the concurrency construct is a single global event-loop that calls tasks/microtasks.
Callbacks themselves, however, are not a concurrency construct. Thus, comparing them to concurrency constructs is very weird.
(A SAX parser is an example of a non-concurrent use of callbacks.)
> Even using threading with a GIL can create execution paths that you aren't really aware of until you actually look through the code or debug.
It does not create execution paths that are not easily visible (you know nothing about a program until you look through the code), but yes, threading.Thread can lead to some unanticipated behavior.
Note that I was excluding this as a parallelism construct, not a concurrency construct. The behavior will be some form of cooperative multi-tasking.
EDIT: too much "however".