The Primary Issue: What is a Computer Used For?
There is one issue in software that all other issues follow from:
What is a computer used for?
Computing
Calculation
A computer can be used to calculate mathematical results.
In this perspective, a piece of software is a function with one input and one output.
Error conditions are glued onto this perspective as an after-thought.
This was the primary purpose behind the invention of computers.
Computers were invented to calculate ballistic trajectories of projectiles.
This perspective is inherently synchronous.
I posit that computing, and software development, has outgrown this perspective.
Machine Control
Another perspective for using a computer is to control machinery, such as DAWs (Digital Audio Workstations), injection molding machines, printing machines, etc.
In this perspective, each function can have more than one outcome.
In this perspective, the computer receives inputs from outside sensors and produces control outputs to the outside world.
Input from sensors can come "at any time".
This perspective is inherently asynchronous.
Distributed Computing
Distributed computers come in two flavors
Some computers perform both of the above roles.
Distributed computers receive asynchronous inputs from
- users
- other computers on the network
- (other stuff omitted for brevity)
Synchronous vs. Asynchronous
Several issues are important when discussing synchronicity:
- data delivery
- code invocation
- order of operations
- order of data arrival
Synchronous Behaviour
Data Devliery
- parameters deliver input data
- output data is sent - only to the caller - via RETURN statements
- error data is sent - only up the dynamic call chain - via exception statements, e.g. throw
Code Invocation
- actions are invoked by the CALL statement
- actions use input data (from parameters)
- actions produce output data and exceptions
Ordering
- (1) inputs are delivered (via parameters), then (2) code is invoked - all of this is subsumed into the CALL statement
- (3) actions produce outputs or exceptions
- caller waits for callee to perform its action
Asynchronous Behaviour
Data Devliery
- data is delivered via Send()
- there is no difference between parameters, return values and exceptions - they are all data delivered by Send()
- data can be directed (Send()) to any component, not just the caller and the dynamic call-chain
Code Invocation
- at its most basic, actions are invoked for each piece of data received from Send() operations, e.g. fn(a,b,c) would invoke 3 actions - fn(a), fn(b) and fn(c)
- various permutations of this behaviour have been posited,
- for example, the misleadingly-named, dataflow model invokes actions only after all inputs have arrived
- for example, FBP (Flow-Based Programming) invokes actions only when a read statement is waiting for input on a particular port
Ordering
- in the asynchronous model, data delivery and action invocation are not tied together, e.g. many pieces of data can be sent before any action is invoked
- CALL does not exist
- parameter delivery is divorced from action invocation
- RETURN values are delivered via Send() and imply no action invocation(s)
- exception values are delivered via Send() and imply no action invocation(s) ; since Send() supplants syntactic sugar like throw, error data can be sent to any component and does not imply immediate action invocation
- Ordering is "arbitrary" and controlled only by a dispatcher function [N.B. dispatchers are commonly used in operating system threads, but, operating systems impose a synchronous behaviour style on all contained actions - such threading protocol is not necessary, despite commonly-held beliefs]
Simplicity
Simplicity is the lack of nuance.
Simplicity results when an appropriate programming paradigm is used.
How To Pick A Paradigm?
How does one decide which paradigm to use?
Firstly, one must ask the right questions, then apply the principles of Divide & Conquer.
Example: Synchronous Paradigm
- To build a calculator: the synchronous paradigm is appropriate.
We have seen this paradigm - the synchronous paradigm - evolve into what we call Functional Programming.
Example: Aynshcronous Paradigm
- To build a controller, use the asynchronous paradigm.
- See also: Harel Statecharts http://www.inf.ed.ac.uk/teaching/courses/seoc/2005_2006/resources/statecharts.pdf
Accidental Complexity
- Using the wrong paradigm will lead to accidental complexity.
- E.G. Threads grafted onto the synchronous paradigm.
- We have seen this evolve into the commonly-held belief that multitasking is hard.[1]
Examples of Synchronous and Asynchronous Paradigms
I discuss concrete examples below.
Example: Cryptography
Cryptography is a mathematical function of one input which produces one output.
Cryptography is a calculator.
The synchronous paradigm is appropriate for cryptography.
Example: DAW
A DAW - digital audio workstation - is a controller. It takes inputs from the user and from a clock and produces outputs, e.g. MIDI, that control various devices (sound generators, envelope generators, etc.)
The asynchronous paradigm is most suited to programming a DAW.
GUI
- Graphical User Interface - accepts inputs from a user, then performs actions based on those inputs.
- The inputs come at unpredictable times.
- Use asynchronous paradigm.
- Using more than one paradigm is OK
- e.g. if the actions, that a GUI performs, are sufficiently complex, one might switch to programming the actions in the synchronous paradigm).
- Current practice: We currently don't favour programming in anything but the synchronous paradigm, hence, GUIs tend to be programmed in the synchronous paradigm with bandaids that allow programmers access to asynchronous behaviours.
P2P - Peer To Peer
- P2P - Peer-to-Peer sharing, was popularized by Napster and SETI.
- primarily an asynchronous protocol that shares data and resources between several computers.
- Asynchronous Data
- The primary activity of p2p is to listen for asynchronous communications and to accept data (asynchronously) from other peer computers on the network.
- Timers:
- Another activity of p2p is to push chunks of resources to other peer computers. To achieve resource pushing without flooding the network and exhausting its own upload bandwidth, p2p must use timers, which, from the software perspective, raise timeout events asynchronously.
- asynchronous paradigm
Blockchain
- 2 paradigms
- Synchronous
- Asynchronous
- protocols between distributed computers.
- calculations performed in the synchronous paradigm
- distributed protocols performed in the asynchronous paradigm,
Browsers, HTML, Internet
- Browser are the new manifestation of GUIs.
- Asynchronous
- Browsers communicate with server computers in a distributed fashion.
- Practice:
- popular programming tools and languages for the asynchronous paradigm are not common, hence, internet programming is performed with a grab-bag of low-level operations, including JavaScript, node.js, etc.
- The GO language has been evolved to provide better access to low-level functionality in the asynchronous paradigm, but GO is based on synchronous belief structures and, is, thus, not the simplest solution to the problem(s).
Text Editing & Layout
- Text editing tools tend to be one-in-one-out programs.
- e.g. LaTeX,
- etc.
- Synchronous paradigm
[1] Multitasking is hard only if one attempts to solve the multitasking problem using the synchronous paradigm.