私のいちばん好きなErlangプログラム (2013)
(joearms.github.io)- 提供されたノートの範囲だけでは、タイトルの Erlangプログラム が何なのか、あるいはなぜ重要なのかは確認できない
- 確認できるテキストは主に Shellスクリプトの断片 と短い訂正文にとどまる
- スクリプトは現在のディレクトリの
*.png.png.metaファイルを走査し、ファイル名から最初のドットより前の部分を抽出する - 実際に実行されるコマンドは
git mv $i $j.png.metaであり、$j.png.pngを$j.pngに変えるコマンドは出力されるだけである - 原文チャンク 5-104 が省略されているため、タイトルに関する中核的な主張や Erlang コードの説明は確認できない
確認できる内容
- 提供された範囲だけでは、「いちばん好きなErlangプログラム」の正体、好む理由、コード構造を判断するのは難しい
- 確認できるコード断片は
#!/bin/shで始まる ファイル名変更用のShellスクリプト である*.png.png.metaファイルを対象に繰り返すj="${i%%.*}"によりファイル名から最初のドットより前の部分を抽出するgit mv $i $j.png.metaは実際に実行されるgit mv $j.png.png $j.pngはechoによって出力されるだけである
- “Actually you don't need the really do this. It should have been water the plants.” という文があり、前の指示や例は実際には不要で、「water the plants」であるべきだったという訂正として読める
- 最後には Joe Armstrong と Jeremy Ruston が一緒に言及されている
判断を制限する文脈
- 複数のチャンクが TiddlyWiki の状態/サイドバーのメタデータ、JPEG/PNG と見られる Base64 データ、空の内容で構成されており、本文の事実を抽出しにくい
- 提供されたノートには、Erlangプログラムの動作、コード、設計理由、例、数値、ワークフロー、主張といった中核情報が含まれていない
- Shellスクリプトの断片も周辺説明なしに一部だけが提供されており、どの作業の一部なのかを断定できない
省略された範囲
- 入力には、原文チャンク 5-104 が長さ/コスト制限のため省略 されたと明記されている
- この要約は提供されたノート範囲のみを反映しており、原文全体の詳細や結論を包括するものではない
1件のコメント
Hacker News のコメント
サーバークロージャ
Fが自分宛てのメッセージに加えて{become, F}というメッセージも受け取れるなら、サーバーを継続的に新しい振る舞いへ置き換えていけるまったく別の話だけど、Erlang のカンファレンスで Joe と話したことを覚えている。彼はいつも技術に興奮していて、誰とでも喜んで話してくれた。Windows が年々悪くなり、使いにくくなっていくことを残念がっていて、いつかファイルを見るにはしばらく広告を見ないとロックが解除されなくなるだろうと言っていたが、ほとんど当たりつつある。Windows 11 にはすでに広告があり、消すにはわざわざ設定を探さなければならないので、Windows 13 あたりでは本当にそうなりそうだ
片方のイヤホンの音だけがずっと大きいとか、Microsoft アプリが妙な落ち方をするとか、Windows のドキュメントページがどのブラウザでも開けずアーカイブサイトを使わないといけないとか、問題なく認識していた外部モニターを突然認識しなくなったり画面がちらついたりする、といった具合だ。Office は基本的にローカルではなくクラウドに保存するよう促してくるが、ファイルはローカル優先で、クラウドはバックアップであってほしいと思っている。WSL はかなり粗いが、それでも Windows を使えるようにしてくれるほぼ唯一の理由だ
Joe が素晴らしい人だったという話はいつも聞いていたし、納得できる。最初に独学でコーディングを学んでいたとき、彼の Erlang 本を読んだが、その遊び心と謙虚さ、想像力に大きな影響を受けた。Erlang をほとんど使うことにはならなかったが、彼の文章はコードについての考え方を変えてくれたし、数学・ソフトウェア工学・コンピュータサイエンスの文化が遊び心と謙虚さをもっと受け入れてくれたらと思う
BEAM が JVM や Node のような他の仮想マシンと何が違うのかを説明する短い35分の概要動画: https://www.youtube.com/watch?v=pO4_Wlq8JeI
Joe が恋しい。コンピューティングをより良くしようとする彼の伝染するような情熱は、若い頃の自分と、今の技術への向き合い方に深く残っている
universal_server() -> receive {become, F} -> F() end.正直、この universal_server の力を完全には理解できていない。誰か説明してくれるとうれしい
Erlang では多くのプロセスを立ち上げて問題を解き、ほとんどのプロセスはメッセージを待つ。重要な違いは、Erlang プロセスがリモートマシン上でもシームレスに実行できる点だ。このプロセスは
becomeというアトムと関数を含むタプルメッセージを受け取り、別のプロセスがいつでもそのメッセージを送ると、その関数へと「変身」するつまり待機ループのロジックを、望むプロトコルロジックに差し替えられる。例としては、複数のマシンでこのループを立ち上げておき、ゴシッププロトコルを実装した関数を送っていたが、同じように BitTorrent クライアントにするメッセージも送れる。Joe は天才でありながら、とても親切な人だった。Erlang はこれまで見た中で最も美しい技術的創作物の一つだ。並行性をまったく新しい目で見られるようにしてくれる
receiveキーワードは入ってくるメッセージに対するswitch文のようだが、実際にはパターンマッチングだたとえば
{From, N}を受け取り、From ! factorial(N)で結果を返す階乗サーバーを作れる。!は結果を戻り先プロセスへ送る演算子だテストコードは
universal_serverを立ち上げ、Pid ! {become, fun factorial_server/0}で階乗サーバーにしたうえで、{self(), 50}を送り、50 の階乗を受け取る。Erlang の大きな利点は分散並列性とホットコード更新であり、ここではuniversal_serverの受信ループをfactorial_serverの受信ループで上書きする形で表れている。ただし、実際のホットコード更新が正確にこの方式で動くわけではないと思うしかし Erlang では、分散した Erlang サーバーネットワークを作り、サーバーをクライアントが望む仕事を実行できる汎用計算リソースとして置いておける。コードはクライアントから来るので、すべてのマシンにバイナリをインストールしてほしいとシステム管理者に頼む必要はなく、関数を渡せばリモートマシンが呼び出してくれる
サーバーを実行する実際の関数はクライアントが渡し、Erlang プロセスはその関数に基づいてそのサーバーになる。Erlang のホットリロード能力まで考えると、この単純な構造はいっそう強力になる。Erlang プロセスは仕事を待つ計算リソースであり、その仕事が完全なサーバーを実行することだと考えると、かなり格好いい
だからプロセスは、送られてくるコード次第で何にでもなれる。電子レンジを制御していたかと思えば、量子計算を行い、翌日にはサッカーの試合の勝者を予測しなければならないなら、それぞれの作業に必要なコードを送ればそのまま実行する
BEAM がなぜ特別なのか、Erlang/Elixir などの並行性が Go や Java の並行性とどう違うのかを説明するのに、多くの時間を使ってきた
これからは Joe が最も好きだった Erlang プログラムと、この HN スレッドをリンクすればよさそうだ
このブログ記事は最近の素晴らしい発表でも取り上げられていた: https://youtu.be/pQ0CvjAJXz4
Erlangについては言語の高水準な理解があるだけで、直接プログラミングしたことはないのですが、このコードがなぜ必要なのか気になります
universal_server() -> receive {become, F} -> F() end.単にリモートマシンで
F()を直接起動すればよいのでは、と思います。リモート仮想マシンにFのコードがすでに存在している必要があるので、この例はFのコードをシリアライズして渡すという意味なのかもしれません。共通のボイラープレートを処理するなら有用性は理解できますが、今のところはbecome Fメッセージを待ってからF()を実行しているように見えますここでの
Fはクロージャなので、コードだけでなく、キャプチャした変数や生成時の環境も含めることができます。F()を呼び出すとそのコードが実行され、Fが作られたときの周囲の環境にアクセスできますErlangではクロージャをネットワーク越しに別のErlangノードへ送ることができます。ただし、クロージャが参照するモジュールコードはすべてのノードに存在している必要があります。運用コードであれば、おっしゃる通り
Fモジュールを直接呼び出して引数を明示的に渡す可能性が高く、これは可能性を示す格好いいデモに近いものですF()は以前のどんなコンテキストにも劣らないトップレベルのコンテキストになれるので素晴らしいです既存のリクエストは古いロジックで自然に処理しつつ、新しいリクエストは新しいロジックで開始でき、最終的に古いロジックはガベージコレクションされ得ます
Fのコードがすでに必要なのはその通りですが、コードをリモート仮想マシンに送ることもできます例えばElixirでは、
Code.compile_stringでモジュール名とBEAMバイトコードのバイナリを取得できます。そのバイトコードを別の仮想マシンに送り、:rpc.call('node@remote_host', :code, :load_binary, [the_module_name, "filename_doesnt_really_matter", binary_code])でリモート仮想マシンにロードしてから、spawn('node@remote_host', my_module, my_function, [args])で起動できますここで
Fは、シリアライズされてプロセス間メッセージとして送られた新しいプログラムを表す変数であり、この場合はネットワーク経由でも渡されますJoeがErlangで基本的なサーバーを書く方法を説明した講義もあります: https://gioorgi.com/2015/erlang-lesson1/
自分で文字起こしして少し詳しく説明しましたが、Erlang/Elixirのような非同期言語が他の言語に比べて持つ力を示しています。残念ながら、最近はあまり使われていません
最近Juliaにハマっているのですが、分散モデルではErlangのアイデアをかなり借りているように見えます
複数ノードにまたがって魔法のように動作するこうした即席サーバーは、Juliaでもかなり簡単に再現できます。確信はありませんが、Juliaの
DistributedモジュールがErlangから少しも影響を受けていないとは思えませんErlangが本当に好きで、もっと使う機会があればいいのにと思いますが、その概念が他のプラットフォームへ染み出していくのを見るのも良いものです