[Translation] Joe Armstrong on Elixir, Erlang, OP and OOP

[Translation] Joe Armstrong on Elixir, Erlang, OP and OOP

A number of articles have been published on Habré in the last few days, a common leitmotif of which (especially in the comments) was the confrontation between blunt-pointed and pointed-points - adherents of FC versus OOP, although they were urged not to argue. Sometimes they discussed Erlang, in connection with which I remembered a short post on a topic from Joe Armstrong, one of the creators of this language, written by him at the end of 2018 on the Elixir forum in response to a question about the paradigm of the language. I think his comment will be interesting.

Joe Armstrong, September 12, 2018

Everything good about Elixir (and Erlang) is related to concurrency - the simple creation of independent processes and the exchange of messages. And this is precisely the very essence of object-oriented programming, as Alan Kay has repeatedly pointed out.

OOP is completely devoted to objects. Objects respond (or should respond) to messages, and when you want to do something — you send a message to the object, and it doesn't matter how it processes it. Think of objects as "black boxes", and when you want something from them - just send messages, and they will send you messages in reply.

How everything is arranged inside doesn’t matter - whether the code inside the black box is functional or imperative - all that matters is what it should do.

Unfortunately, although the first successful object-oriented language based on this model (Smalltalk) and operated with the concepts of "object" and "message", the latter in Smalltalk were not real messages, but only disguised synchronous function calls. The same mistake was repeated in C ++, then in Java, and the main idea of ​​OOP degenerated into a strange paradigm of organizing code by classes and methods.

Erlang and Elixir provide easy creation of millions of isolated processes, where everything works through the sending of messages between them. The system architecture is determined by the level of parallelism that you desire, followed by mapping it to the processes directly.

The Elixir web server for 10,000 users is not "one web server with 10,000 users" (as is the case with Apache or Jigsaw and the like), but it is "10,000 web servers per user" - agree a radical departure from the traditional model.

The fact that a simple functional language was used to describe the Erlang/Elixir process model is almost an accident. It all started with a logic programming system (Prolog), and such things as, for example, C-node, can be written in general in any language. Truly important for Elixir (and any other BEAM-language) is the ability of their virtual machine to operate with an extremely large number of parallel processes.

For a long time, I said that "Erlang is the only real object-oriented language." Probably now I can add Elixir to it.

For OOP, the basic things are:

  • isolation between objects (we have it)
  • late binding (we decide what to do only when the process receives a message)
  • polymorphism (all objects can respond to a message of the same type, for example, "print-yourself" and any object can know how to do it)

Much less important:

  • division into classes and methods
  • syntax
  • software model (functional or imperative)

After we have divided the system into a large number of small, communicating processes, everything else becomes (relatively) easy - each process should be simple enough and able to do quite a few, which greatly simplifies programming.

< br/>

What Erlang (and Elixir) brought to programming was the idea of ​​links.Originally proposed by Mike Williams, it is to expand the possibility of error handling, allowing it to be done beyond the bounds of processes. Having this, we got all the necessary tools for building trees, supervisors, etc.

Supervisors, gen_servers and all that sort of stuff are just libraries that hide some details from the user. Simple inside, written using the same tools - parallel processes and links between them.

Erlang was not designed as a functional programming language, but as a tool for creating long-lived fault-tolerant systems.

The core element of fault tolerance is the notion of remote error handling. If the entire system fails, the fault must be corrected (compensated) on another machine, since it is already impossible to do this locally - the local computer does not work.

This means that for programming fault-tolerant systems, we need distribution (processes) and messaging to be easy-to-use tools, which is why, in principle, any fault-tolerant architecture will ultimately look like Erlang.

< br/>

The whole point of creating Erlang was to simplify the programming of fault-tolerant systems, a side effect of which was the ease of programming scalable systems.

The difference between Erlang and Elixir and “all others” lies in the mechanisms for ensuring concurrency and fault tolerance, and this is not about monads, syntax, or “cleanliness” of OP.

Now the question is - do you want to process 10,000 users in one thread, using callbacks to emulate concurrency, or do you still want to create 10,000 parallel processes, each of which is simple and does not need callbacks at all?

< br/>

Each process waits for a message in which it is interested, then performs calculations and goes to sleep waiting for the next one.

I think the big problem with promoting Erlang/Elixir is that you need to explain how a large number of parallel processes help solve your particular problem. Since no other common languages ​​are initially aimed at parallel programming and do not facilitate it in any meaningful way, the need for it for people is not fully understood and understood.

"But I can do everything on callbacks in one thread," they will say. And they do it, and it is painfully difficult. And you ask “what will happen if the callback falls into a cycle or causes an exception?”, And if they do not understand the question, then you must work hard and explain the problem. But if the question is clear - then tell them that there is one distant country where callbacks are not needed for programming concurrency.

It seems that all of the above can be reduced to the following: please do not advertise Elixir as a functional programming language - it is not. It is a parallel programming language (CPL, Concurrent Programming Language).

Do not respond to arguments like "my functional language is more functional than yours." And do not even think about talking about monads, immediately change the subject.

"- What is CPL?"
"- You know, this is what WhatsApp is made of ..."

From the translator

First of all, I would like to express regret in connection with the sudden death of Joe Armstrong - he died on April 20, 2019. It is difficult to underestimate his contribution to the development of the industry, as well as his talent as a popularizer - books, speeches, and active work in the Erlang and Elixir communities.

Useful links:

Source text: [Translation] Joe Armstrong on Elixir, Erlang, OP and OOP