True isolation is
CALL / RETURN
CALL/RETURN does not isolate control-flow, it implies sequential operation.
var x = obj.method (...) is sequential.
Relational programming does not imply sequential operation.
All control flow is handled by the relational engine.
UNIX threads do not imply sequential operation.
Uber control flow is handled by the dispatcher.
Functions Are Sequential
fn(a)->b implies sequential operation.
The parameters are delivered in a “sequential block” (all parameters are delivered at the same time).
The return value is delivered in a “sequential block”.
The caller waits for a result.
Concurrency vs. Parameters
Note that sequentialism leaks into parameter passing.
In sequential programming, all parameters must be delivered at the same time.
In concurrent programming, parameters can be delivered
- at any time
- in any order
Grouping parameters together and grouping return values together is the exception, not the rule, in concurrent programming.
Lifetime - Forever vs. Live-Then-Die
The caller does/can not care if the callee
- (a) lives forever, or,
- (b) lives-then-dies.
(a) is server-like.
(b) is function-like.
Need to Know
x.fn(...) implies that you know too much about “x”.
That knowledge is hard-wired into the calling code and makes it hard to change later, aka accidental dependency.
Suggestion: all methods have only one calling syntax and all methods have the same parameter list syntactically, with the same type (!).
The suggestion is not to delete type-checking, but to move it elsewhere.
We already do this with compilers -> opcodes.
Compilers can be viewed as type filters that strip away semantic information to produce untyped opcodes.
var x = obj.method (...), you do not get to choose whether the operation is concurrent or sequential.
The choice is made for you and baked into your code (aka accidental dependency (aka accidentally not-isolated)).
Suggestion: code cannot call a method in an object.
Code can only send information to its parent.
The parent can choose to send this information to another child for further processing.
I.E. a function cannot name other objects and methods.
Software components can contain code.
Software components can only send information upwards to their parents, or, they can send commands to their children.
Cross-talk is not allowed.
Cross-talk produces non-scalable code.
Corollary: components cannot communicate directly with their peers.