Mein Lieblings-Erlang-Programm (2013)
(joearms.github.io)- Aus dem bereitgestellten Notizbereich allein lässt sich weder feststellen, welches Erlang-Programm im Titel gemeint ist, noch warum es wichtig ist
- Der überprüfbare Text besteht überwiegend aus Shell-Skript-Fragmenten und einem kurzen Korrektursatz
- Das Skript durchläuft
*.png.png.meta-Dateien im aktuellen Verzeichnis und extrahiert aus dem Dateinamen den Teil vor dem ersten Punkt - Der tatsächlich ausgeführte Befehl ist
git mv $i $j.png.meta, während der Befehl zum Umbenennen von$j.png.pngin$j.pngnur ausgegeben wird - Da die Original-Chunks 5-104 ausgelassen wurden, lassen sich die Kernaussagen zum Titel oder eine Erklärung des Erlang-Codes nicht verifizieren
Überprüfbare Inhalte
- Auf Grundlage des bereitgestellten Bereichs ist schwer zu beurteilen, was genau das „Lieblings-Erlang-Programm“ ist, warum es bevorzugt wird oder wie die Codestruktur aussieht
- Das überprüfbare Codefragment ist ein Shell-Skript zum Umbenennen von Dateien, das mit
#!/bin/shbeginnt- Es iteriert über
*.png.png.meta-Dateien - Mit
j="${i%%.*}"wird der Teil des Dateinamens vor dem ersten Punkt extrahiert git mv $i $j.png.metawird tatsächlich ausgeführtgit mv $j.png.png $j.pngwird nur perechoausgegeben
- Es iteriert über
- Es gibt den Satz „Actually you don't need the really do this. It should have been water the plants.“, der als Korrektur zu lesen ist, dass die vorherige Anweisung oder das Beispiel eigentlich nicht nötig war und stattdessen „water the plants“ hätte stehen sollen
- Am Ende werden Joe Armstrong und Jeremy Ruston gemeinsam erwähnt
Kontext, der die Beurteilung einschränkt
- Mehrere Chunks bestehen aus TiddlyWiki-Status-/Sidebar-Metadaten, Base64-Daten, die wie JPEG/PNG aussehen, oder leerem Inhalt, sodass sich schwer Tatsachen aus dem Haupttext extrahieren lassen
- Die bereitgestellten Notizen enthalten keine Kerninformationen wie das Verhalten des Erlang-Programms, den Code, Designgründe, Beispiele, Zahlen, Workflow oder zentrale Behauptungen
- Auch das Shell-Skriptfragment wird nur teilweise und ohne erläuternden Kontext gezeigt, sodass nicht sicher bestimmbar ist, zu welcher Aufgabe es gehört
Ausgelassener Bereich
- In der Eingabe wird ausdrücklich angegeben, dass die Original-Chunks 5-104 aus Längen-/Kostengründen ausgelassen wurden
- Diese Zusammenfassung spiegelt nur den bereitgestellten Notizbereich wider und deckt weder alle Details noch die Schlussfolgerung des vollständigen Originaltexts ab
1 Kommentare
Hacker-News-Kommentare
Wenn die Server-Closure
Fneben ihrer eigenen Nachricht auch eine Nachricht{become, F}empfangen kann, kann man den Server fortlaufend durch neues Verhalten ersetzen.Ganz anderes Thema, aber mir ist in Erinnerung geblieben, wie ich auf einer Erlang-Konferenz mit Joe gesprochen habe. Er war immer begeistert von Technik und sprach bereitwillig mit jedem. Er bedauerte, dass Windows von Jahr zu Jahr schlechter und weniger brauchbar wurde, und meinte, irgendwann müsse man erst eine Weile Werbung ansehen, um eine Datei sehen zu dürfen – damit lag er fast richtig. In Windows 11 gibt es bereits Werbung, und wenn man sie entfernen will, muss man absichtlich die Einstellungen suchen; bei Windows 13 dürfte es also wirklich so weit sein.
Etwa dass ein Ohrhörer deutlich lauter ist als der andere, Microsoft-Apps seltsam abstürzen, Windows-Dokumentationsseiten sich in keinem Browser öffnen lassen und man Archivseiten verwenden muss, ein zuvor problemlos erkannter externer Monitor plötzlich nicht mehr erkannt wird oder der Bildschirm flackert. Office drängt standardmäßig dazu, nicht lokal, sondern in der Cloud zu speichern; ich bin eher der Meinung: Dateien sollten lokal zuerst liegen, und die Cloud sollte Backup sein. WSL ist ziemlich holprig, aber immerhin fast der einzige Grund, warum Windows überhaupt noch nutzbar ist.
Ich habe immer gehört, dass Joe ein großartiger Mensch war, und das leuchtet mir ein. Als ich mir das Programmieren anfangs selbst beigebracht habe, las ich sein Erlang-Buch; seine Verspieltheit, Bescheidenheit und Vorstellungskraft haben mich stark geprägt. Erlang habe ich letztlich kaum verwendet, aber seine Texte haben meine Denkweise über Code verändert, und ich wünschte, die Kultur von Mathematik, Software Engineering und Informatik würde Verspieltheit und Bescheidenheit stärker annehmen.
Ein kurzer 35-minütiger Überblick als Video darüber, warum sich die BEAM von anderen virtuellen Maschinen wie JVM oder Node unterscheidet: https://www.youtube.com/watch?v=pO4_Wlq8JeI
Joe fehlt mir. Seine ansteckende Leidenschaft, Computing besser zu machen, hat mein jüngeres Ich und meine heutige Herangehensweise an Technik tief geprägt.
universal_server() -> receive {become, F} -> F() end.Ehrlich gesagt verstehe ich die Stärke dieses universal_server nicht vollständig. Es wäre schön, wenn das jemand erklären könnte.
In Erlang startet man viele Prozesse, um ein Problem zu lösen, und die meisten Prozesse warten auf Nachrichten. Der wichtige Unterschied ist, dass Erlang-Prozesse nahtlos auch auf entfernten Maschinen laufen können. Dieser Prozess empfängt eine Tupel-Nachricht, die das Atom
becomeund eine Funktion enthält; sobald ein anderer Prozess ihm diese Nachricht schickt, „verwandelt“ er sich in diese Funktion.Das heißt, man kann die Logik der Warteschleife durch die gewünschte Protokolllogik austauschen. Im Beispiel wurden diese Schleifen auf mehreren Maschinen gestartet und ihnen eine Funktion zur Implementierung eines Gossip-Protokolls geschickt; man könnte ihnen aber genauso gut eine Nachricht schicken, die sie zu BitTorrent-Clients macht. Joe war ein Genie und zugleich ein sehr freundlicher Mensch, und Erlang ist eine der schönsten technischen Schöpfungen, die ich je gesehen habe. Es lässt einen Nebenläufigkeit völlig neu betrachten.
receivewirkt wie eineswitch-Anweisung für eingehende Nachrichten, ist tatsächlich aber Pattern Matching.Man könnte zum Beispiel einen Fakultätsserver bauen, der
{From, N}empfängt und mitFrom ! factorial(N)das Ergebnis zurückschickt.!ist der Operator, der das Ergebnis an den Rückgabeprozess sendet.Der Testcode startet
universal_server, macht ihn mitPid ! {become, fun factorial_server/0}zu einem Fakultätsserver und schickt dann{self(), 50}, um die Fakultät von 50 zurückzubekommen. Erlangs große Stärken sind verteilte Parallelität und Hot Code Updates, und hier zeigt sich das in der Form, dass die Empfangsschleife vonuniversal_serverdurch die Empfangsschleife vonfactorial_serverüberschrieben wird. Ich denke allerdings, dass echte Hot Code Updates nicht exakt so funktionieren.In Erlang kann man jedoch ein Netzwerk verteilter Erlang-Server aufbauen und die Server als universelle Rechenressourcen bereitstellen, die tun können, was der Client möchte. Der Code kommt vom Client; statt einen Systemadministrator bitten zu müssen, auf allen Maschinen ein Binary zu installieren, übergibt man eine Funktion, und die entfernte Maschine ruft sie auf.
Die tatsächliche Funktion, die den Server ausführt, wird vom Client übergeben, und der Erlang-Prozess wird auf Basis dieser Funktion zu diesem Server. Berücksichtigt man zusätzlich Erlangs Fähigkeit zum Hot Reloading, wird diese einfache Struktur noch mächtiger. Ein Erlang-Prozess ist eine Rechenressource, die auf Arbeit wartet; wenn diese Arbeit darin besteht, einen vollständigen Server auszuführen, ist das ziemlich cool.
Deshalb kann ein Prozess je nach dem Code, den man ihm schickt, alles Mögliche werden. Wenn er erst eine Mikrowelle steuern, dann Quantenberechnungen durchführen und am nächsten Tag den Sieger eines Fußballspiels vorhersagen soll, schickt man ihm den für die jeweilige Aufgabe nötigen Code, und er führt ihn aus.
Ich verbringe viel Zeit damit zu erklären, warum die BEAM besonders ist und warum Nebenläufigkeit in Erlang/Elixir usw. anders ist als in Go oder Java.
Ab jetzt kann ich wohl einfach auf Joes Lieblingsprogramm in Erlang und diesen HN-Thread verlinken.
Dieser Blogbeitrag wurde auch in einem neueren, hervorragenden Vortrag behandelt: https://youtu.be/pQ0CvjAJXz4
Von Erlang habe ich nur ein grundlegendes Verständnis auf höherer Ebene und habe nie selbst damit programmiert; deshalb frage ich mich, wozu dieser Code nötig ist:
universal_server() -> receive {become, F} -> F() end.Könnte man nicht einfach
F()direkt auf der entfernten Maschine starten? Auf der entfernten virtuellen Maschine müsste der Code fürFbereits vorhanden sein, daher könnte dieses Beispiel auch bedeuten, dass der Code vonFserialisiert und übertragen wird. Wenn damit gemeinsamer Boilerplate-Code erledigt wird, verstehe ich den Nutzen, aber im Moment sieht es so aus, als würde es auf einebecome F-Nachricht warten und dannF()ausführen.Fist hier eine Closure und kann daher nicht nur Code enthalten, sondern auch erfasste Variablen und die Umgebung zum Zeitpunkt ihrer Erzeugung. Wenn manF()aufruft, wird dieser Code ausgeführt und kann auf die Umgebung zugreifen, in derFerstellt wurde.In Erlang kann man Closures über das Netzwerk an andere Erlang-Nodes senden. Allerdings muss der Modulcode, auf den die Closure verweist, auf allen Nodes vorhanden sein. In produktivem Code würde man, wie gesagt, wahrscheinlich das Modul
Fdirekt aufrufen und die Argumente explizit übergeben; das hier ist eher eine coole Demonstration dessen, was möglich ist.F()ein ebenso guter Top-Level-Kontext sein wie jeder vorherige Kontext; das ist ziemlich elegant.Bestehende Requests können auf natürliche Weise mit der alten Logik weiterverarbeitet werden, während neue Requests mit der neuen Logik starten, und am Ende kann die alte Logik per Garbage Collection aufgeräumt werden.
Fbereits auf der entfernten virtuellen Maschine vorhanden sein muss, aber man kann Code auch an die entfernte virtuelle Maschine senden.In Elixir kann man zum Beispiel mit
Code.compile_stringden Modulnamen und das BEAM-Bytecode-Binary erhalten. Diesen Bytecode kann man an eine andere virtuelle Maschine senden und mit:rpc.call('node@remote_host', :code, :load_binary, [the_module_name, "filename_doesnt_really_matter", binary_code])in die entfernte virtuelle Maschine laden und ihn anschließend mitspawn('node@remote_host', my_module, my_function, [args])starten.Fist hier eine Variable, die für das neue Programm steht, das serialisiert und als Nachricht zwischen Prozessen gesendet wurde; in diesem Fall wird es auch über das Netzwerk übertragen.Es gibt auch eine Vorlesung, in der Joe erklärt, wie man in Erlang einen einfachen Server schreibt: https://gioorgi.com/2015/erlang-lesson1/
Ich habe sie selbst mitgeschrieben und noch etwas ausführlicher erklärt; sie zeigt die Stärke von asynchronen Sprachen wie Erlang/Elixir gegenüber anderen Sprachen. Schade, dass sie heutzutage nicht mehr viel genutzt werden.
In letzter Zeit bin ich ziemlich in Julia vertieft, und es sieht so aus, als hätte es für sein verteiltes Modell einige Ideen aus Erlang übernommen.
Solche Ad-hoc-Server, die wie von Zauberhand über mehrere Nodes hinweg funktionieren, lassen sich auch in Julia recht einfach nachbauen. Sicher bin ich nicht, aber es scheint kaum vorstellbar, dass Julias Modul
Distributednicht zumindest ein wenig von Erlang inspiriert wurde.Ich mag Erlang wirklich sehr und wünschte, ich hätte mehr Gelegenheiten, es zu verwenden; aber es ist auch schön zu sehen, wie diese Konzepte in andere Plattformen einsickern.