January 31st, 2016
(written by lawrence krubner, however indented passages are often quotes). You can contact lawrence at: email@example.com
I am puzzled why good ideas so rarely win out in the tech world. I do know the old saying “Most industries have a top player with the best marketing and the second best technology, with a second place player that has the best technology and mediocre marketing.” Back in the 1990s it was common to apply that slogan to Microsoft and Apple (when Apple had mediocre marketing! Such long forgotten days!).
Still, the lack of innovation in this industry is astounding. Lisp is still an ignored approach to computer programming, TCP/IP consolidated in 1978 and has seen almost no improvement, despite all that was learned about computer networks since then, and Joe Armstrong’s ideas on Concurrency Oriented Programming and Fail Fast are still mostly ignored. It’s sad.
I exaggerate, but not by much.
Why do we have monolithic projects? I believe this is because it is difficult to build communicating components in what are essentially sequential programming languages. Concurrency has been forgotten in most programming languages, and when it has been added it seems like a afterthought, not as an act of conscious design.
In a very large number of programming languages the only way to program a concurrent application is to “do it yourself” and simulate concurrency by storing the state of a suspended process in a data base or some equally horrid constructions involving a mess of callback and promises.
Sequential languages are designed to write sequential programs, and the only way for a sequential program to grow in functionality is for it to get larger. It’s technically difficult to split it into cooperating processes so this is not usually done. The concurrency in the application cannot be used to structure the application.
We should grow things by adding more small communicating objects, rather than making larger and larger non-communicating objects.
Concentrating on the communication provides a higher level of abstraction than concentrating on the function APIs used within the system. Black-box equivalence says that two systems are equivalent if they cannot be distinguished by observing their communication patterns. Two black-boxes are equivalent if they have identical input/output behavior.
When we connect black boxes together we don’t care what programming languages have been used inside the black boxes, we don’t care how the code inside the black boxes has been organized, we just have to obey the communication protocols.
If you look at most GitHub projects – they are built as monolithic single language applications, they are not built from small communicating components written in different languages.
In the Internet world, we program differently. Here it is possible to structure applications as micro-services usually using HTTP-over-TCP or JSON-over-TCP AJAX and so on, but this is not used internally inside the OS to any large extent.
Erlang programs are the exception. Erlang programs are intentionally structured as communicating processes – they are the ultimate micro-services.
Large Erlang applications have a flat “bus like” structure. They are structured as independent parallel applications hanging off a common communication bus. This leads to architectures that are easy to understand and debug and collaborations which are easy to program.