To emphasize the vast chasm in belief structures, imagine CALL/RETURN.
CALL/RETURN restricts the programming domain in several ways:
1. CALL/RETURN performs scheduling (the caller is suspended, the callee runs immediately).
2. Parameters are delivered in a synchronous block - all at the same time.
3. Return Value(s) are delivered in a synchronous block - all at the same time.
4. The Callee springs to life then dies.
5. We (the Royal We) add a kludge, called “Exceptions” to the syntax of CALL/RETURN to compensate for the shortcomings of the kludge that we call CALL/RETURN.
6. CALL/RETURN is implemented - cast in hardware - using a global variable.
We (the Royal We) use an artificial kludge to take control back in situation #1. Operating systems like to think that they control scheduling, but CALL/RETURN violates that notion. Operating systems use “preemption” to wrench scheduling control away from the caller. Preemption comes with its own baggage cart of accidental complexity.
Asynch Components (which includes FBP) drive a stake through the heart of CALL/RETURN. Once you know how to program asynchronously, you can’t unknow how. Until you know this, though, you are only looking at shadows on the wall (often called “thread libraries”, “lazy evaluation”, etc.) and you couch everything in the language of not-knowing.
Note that Relational Programming and FP are - slowly - learning how to expunge CALL/RETURN from notations.
Note that internet programming and distributed programming (e.g. blockchain, p2p) are - slowly - exposing the fallacy of CALL/RETURN.
Thinking-in-async is very, very, very different from thinking-in-sync. Async solutions are very, very, very different from sync solutions for the exact same problem.