In den letzten Tagen wurde eine Reihe von Artikeln über Habré veröffentlicht, deren allgemeines Leitmotiv (insbesondere in den Kommentaren) die Konfrontation zwischen stumpfen und spitzen Personen war - Anhänger der FP gegen die PLO, obwohl sie aufgefordert wurden, nicht zu streiten. Erlang wurde manchmal diskutiert, in Verbindung mit dem ich mich an einen kurzen Beitrag zu einem Thema von Joe Armstrong erinnerte, einem der Schöpfer dieser Sprache, den er Ende 2018 im Elixir-Forum als Antwort auf eine Frage zum Sprachparadigma verfasst hatte. Ich denke, sein Kommentar wird interessant sein.
Joe Armstrong 12. September 2018
Alle guten Dinge an Elixir (und Erlang) hängen mit der Parallelität zusammen - nur mit der Erstellung unabhängiger Prozesse und Messaging. Und genau das ist die Essenz der objektorientierten Programmierung, wie Alan Kay wiederholt betont hat.
OOP ist vollständig Objekten gewidmet. Objekte reagieren (oder sollten antworten) auf Nachrichten. Wenn Sie etwas tun möchten, senden Sie eine Nachricht an das Objekt, und wie es verarbeitet wird, ist völlig irrelevant. Stellen Sie sich Objekte als "Black Boxes" vor, und wenn Sie etwas von ihnen wollen, senden Sie einfach Nachrichten, und sie senden Ihnen als Antwort Nachrichten.
Wie alles im Inneren angeordnet ist, spielt keine Rolle, ob der Code in der Black Box funktional oder zwingend ist - nur was genau er tun soll, ist wichtig.
Obwohl die erste erfolgreiche objektorientierte Sprache, die auf diesem Modell basiert (Smalltalk), auf den Konzepten "Objekt" und "Nachricht" basiert, waren letztere in Smalltalk leider keine echten Nachrichten, sondern nur maskierte synchrone Funktionsaufrufe. Der gleiche Fehler wurde in C ++ und dann in Java wiederholt, und die Hauptidee von OOP entartete zu einem seltsamen Paradigma für die Organisation von Code in Klassen und Methoden.
Erlang und Elixir machen es einfach, Millionen isolierter Prozesse zu erstellen, bei denen alles funktioniert, indem Nachrichten zwischen ihnen gesendet werden. Die Architektur des Systems wird durch den gewünschten Parallelitätsgrad bestimmt, der anschließend direkt den Prozessen zugeordnet wird.
Der Elixir-Webserver für 10.000 Benutzer ist nicht "ein Webserver mit 10.000 Benutzern" (wie dies bei Apache oder Jigsaw und dergleichen der Fall ist), sondern "10.000 Webserver pro Benutzer" - stimmen Sie zu, ein Radikaler Abweichung vom traditionellen Modell.
Die Tatsache, dass eine einfache Funktionssprache zur Beschreibung des Erlang / Elixir-Prozessmodells verwendet wurde, ist fast ein Zufall. Alles begann mit einem logischen Programmiersystem (Prolog), und Dinge wie C-Node können beispielsweise in jeder Sprache geschrieben werden. Das wirklich Wichtige für Elixir (und jede andere BEAM-Sprache) ist die Fähigkeit ihrer virtuellen Maschine, mit einer extrem großen Anzahl paralleler Prozesse zu arbeiten.
Lange Zeit sagte ich: "Erlang ist die einzige echte objektorientierte Sprache." Ich denke jetzt kann ich es und Elixir hinzufügen.
Für OOP sind die grundlegenden Dinge:
- Isolation zwischen Objekten (wir haben es)
- späte Bindung (wir entscheiden nur, was zu tun ist, wenn der Prozess eine Nachricht erhält)
- Polymorphismus (alle Objekte können auf eine Nachricht des gleichen Typs antworten, z. B. "Selbst drucken", und jedes Objekt kann wissen, wie das geht)
Viel weniger wichtig:
- Einteilung in Klassen und Methoden
- Syntax
- Softwaremodell (funktional oder zwingend)
Nachdem wir das System in eine große Anzahl kleiner Prozesse unterteilt haben, die miteinander kommunizieren, wird alles andere (relativ) einfach - jeder Prozess sollte recht einfach sein und einiges leisten können, was die Programmierung erheblich vereinfacht.
Was Erlang (und Elixir) in die Programmierung einbrachten, war die Idee der Kommunikation (Link - ca. Übersetzer). Ursprünglich von Mike Williams vorgeschlagen, besteht es darin, die Möglichkeit der Fehlerbehandlung zu erweitern und sie außerhalb der Grenzen von Prozessen durchzuführen. Damit haben wir alle notwendigen Werkzeuge, um Supervisor-Bäume usw. zu bauen.
Supervisors, gen_server's und all dieser Jazz sind nur Bibliotheken, die einige Details vor dem Benutzer verbergen. Einfach im Inneren, geschrieben mit den gleichen Werkzeugen - parallele Prozesse und die Beziehungen zwischen ihnen.
Erlang wurde nicht als funktionale Programmiersprache entwickelt, sondern als Werkzeug zur Erstellung langlebiger fehlertoleranter Systeme.
Ein zentrales Element der Fehlertoleranz ist das Konzept der Fernfehlerbehandlung. Wenn das gesamte System ausfällt, muss die Fehlfunktion auf einem anderen Computer behoben (kompensiert) werden, da dies bereits lokal nicht möglich ist - der lokale Computer funktioniert nicht.
Dies bedeutet, dass für die Programmierung fehlertoleranter Systeme die Verteilung von (Prozessen) und Messaging einfach zu verwendende Tools sein muss. Daher sieht jede fehlertolerante Architektur im Prinzip wie Erlang aus.
Bei der Erstellung von Erlang ging es vor allem darum, die Programmierung fehlertoleranter Systeme zu vereinfachen. Ein Nebeneffekt war die einfache Programmierung skalierbarer Systeme.
Der Unterschied zwischen Erlang und Elixir und "allen anderen" liegt in den Mechanismen zur Gewährleistung von Parallelität und Fehlertoleranz, und hier geht es nicht um Monaden, Syntax oder "Reinheit" des FP.
Die Frage ist nun: Möchten Sie 10.000 Benutzer in einem Thread verarbeiten und Rückrufe verwenden, um die Parallelität zu emulieren, oder möchten Sie dennoch 10.000 parallele Prozesse erstellen, von denen jeder einfach ist und überhaupt keine Rückrufe benötigt?
Jeder Prozess wartet auf die Nachricht, an der er interessiert ist, führt dann Berechnungen durch und schläft in Erwartung des nächsten ein.
Ich denke, das große Problem bei der Popularisierung von Erlang / Elixir ist, dass Sie erklären müssen, wie viele parallele Prozesse zur Lösung Ihres spezifischen Problems beitragen. Da keine andere gemeinsame Sprache ursprünglich auf parallele Programmierung abzielte und diese in keiner sinnvollen Weise ermöglichte, wird die Notwendigkeit für die Menschen nicht vollständig verstanden und verstanden.
"Aber ich kann alles bei Rückrufen in einem Thread tun", werden sie sagen. Und sie tun es und es ist schmerzlich schwierig. Und Sie fragen: "Was passiert, wenn der Rückruf in die Schleife gerät oder eine Ausnahme auslöst?" Und wenn sie die Frage nicht verstehen, müssen Sie hart arbeiten und das Problem erklären. Wenn die Frage jedoch klar ist, sagen Sie ihnen, dass es ein entferntes Land gibt, in dem Rückrufe nicht erforderlich sind, um Parallelität zu programmieren.
Es scheint, dass all das auf Folgendes reduziert werden kann: Bitte bewerben Sie Elixir nicht als funktionale Programmiersprache - es ist nicht so. Es ist eine parallele Programmiersprache (CPL, Concurrent Programming Language).
Antworten Sie nicht auf Argumente wie "Meine funktionale Sprache ist funktionaler als Ihre." Und machen Sie sich nicht einmal die Mühe, über Monaden zu sprechen, sondern wechseln Sie sofort das Thema.
"- Was ist eine CPL?"
"- Weißt du, das ist es, worauf WhatsApp gemacht ist ..."
Vom Übersetzer
Zunächst möchte ich mein Bedauern über den plötzlichen Tod von Joe Armstrong zum Ausdruck bringen - er starb am 20. April 2019. Es ist schwer zu unterschätzen, welchen Beitrag er zur Entwicklung der Branche geleistet hat und wie talentiert er als Popularisierer ist - Bücher, Reden und aktive Arbeit in den Gemeinden Erlang und Elixir.
Nützliche Links: