はじめに — 「Emacs は OS だ」という誤読
Charles Choi 氏のエッセイ「In Emacs, Everything Looks Like a Service」が、最近 Hacker News で話題になりました。興味深いのは、この文章が「Emacs はオペレーティングシステム(OS)だ」というおなじみの称賛から始めて、それをすぐに否定することです。著者の言い方は明快です。その比喩は正しくなく、OS を連想させるのは、Emacs がカーネルの上でアプリケーションやユーティリティを編成(orchestrate)する能力だ、というのです。
彼が代わりに示す構図のほうが正確です。Emacs はファイルシステムやネットワークといった OS のサービスに直接アクセスでき、他のプログラムを実行できるため、その中でクライアントを即興で作って使うことが日常になります。それこそが「Emacs の中だけで暮らす(living only in Emacs)」という発想に信憑性を与えるのだ、と彼は言います。結論はタイトルそのものです。Emacs の中では、すべてがサービスのように見えます。
ここでの「サービス」は流行語ではなく、正確な技術用語です。本当の主張は、Emacs がデーモンを走らせるサーバーだということではありません。 Emacs は汎用クライアントである ということです。その区別こそがこの文章の核心であり、古い「OS ミーム」よりもはるかに有用なレンズです。
クライアント・サーバーというレンズ
議論の骨格は、教科書的なクライアント・サーバーモデルです。タスクを、資源の提供者(サービス)と要求者(クライアント)に分け、クライアントが要求を出すと、サーバーが応答を返します。この取引はネットワークを越えることも、システム内で局所的に起こることもあります。著者が寄りかかるのは、まさにこの「局所的にも」という点です。
彼は、クライアントがおおむね三つの関心事を担うと整理します。UI、サービスと通信するクライアントエッジ(client edge)、そしてやり取りするデータを収めるローカルデータベースです。そして Emacs には、この三つそれぞれのための組み込みライブラリがすでにあります。UI にはミニバッファ、バッファ、補完、tabulated-list-mode、vtable、transient があり、クライアントエッジには url、TCP/UDP ソケット、SMTP、JSON/XML のシリアライズがあり、ローカルデータには連想リスト、属性リスト、ハッシュテーブル、SQLite があります。これらを束ねる接着剤が Elisp です。実行時に振る舞いを即興で組み立てられる動的言語です。
著者の例は wttr.in という、コンソール向けの天気サービスです。場所を受け取って HTTP 要求を送り、JSON 応答を解析して結果をミニバッファに表示する wttr コマンドを作ります。要点はその分量です。完成した wttr.el は cloc で数えて 67 行です。さらに興味深いのは二つ目の版です。ネットワーク要求と JSON 処理を weather という Python スクリプトに任せると、Elisp 側はシェルを呼ぶだけになります。
(defun weather (location)
"Call weather script with LOCATION and show result in minibuffer."
(interactive "sWhere (default: local): ")
(let* ((weather-cmd "weather")
(cmd (if location (format "%s %s" weather-cmd location) weather-cmd))
(result (shell-command-to-string cmd)))
(kill-new result)
(message result)))
著者の言葉どおり、こうするとシェルコマンド自体が、事実上、要求を送る相手のサービスになります。既存のコマンドラインユーティリティが重い仕事をこなせるなら、そのユーティリティを、シェル呼び出しで到達する一つの「サービス」として捉え直せる、というわけです。この一文が、エッセイ全体を支えています。
なぜこれが独特な計算モデルなのか
ここからは私の読みです。私たちが普段使うモデルは「タスクごとに一つのアプリ」です。ウェブはブラウザ、メールはメールアプリ、シェルはターミナル。各アプリはそれぞれの世界を持ち、その間を行き来するにはコピー&ペーストとウィンドウ切り替えの代償を払います。
Emacs が提示するモデルはその逆です。長く起動しっぱなしの一つの Lisp 環境の中で、それぞれの能力が、あるサービスへの薄いクライアントとして実装されます。天気も、メールも、git も、データベースも、すべてが同じバッファ・同じキーマップ・同じ Elisp の上で動きます。「Emacs の中だけで暮らす」という言い回しが成り立つ理由がこれです。アプリを渡り歩く代わりに、サービスに要求を送るクライアントを、その都度組み立てて足していくのです。
正確に言えば、この文章の主張は、バッファやプロセスそのものがサービスだ、ということではありません。サービスは外側にあります。ネットワーク API か、シェルの向こうの CLI ツールです。Emacs がするのは、それらへのクライアントになることです。だからこのレンズは「Emacs は OS だ」というミームより正確なのです。Emacs はカーネルを置き換えません。その上に載る資源に話しかける、普遍的な窓口になるだけです。
魅力とコスト
魅力は本物で、誇張ではありません。天気クライアント一つが 67 行、CLI を包む版は 9 行です。Unix に存在する数多くのコマンドラインツールが、そのまま呼び出せるサービスになります。統一性も効いてきます。一度覚えた編集・検索・キーマップが、作るすべての「クライアント」にそのまま通用します。組み合わせやすさと即興性。これこそが、このモデルが売る本当の価値です。
コストも同じだけ正直に見るべきです。第一に、著者自身のコードが露わにする代償があります。fetch-json-as-hash-table は url-retrieve-synchronously を使います。同期呼び出しです。Elisp は事実上シングルスレッドなので、要求が飛んでいる間、エディタ全体が止まりうるのです。第二に、抽象は高いのに、配管は自分で握ります。HTTP ヘッダを越えて url-http-end-of-headers までカーソル位置(point)を移し、メモリリークを防ぐためにネットワークバッファを自分で kill-buffer しなければなりません。第三に、より根本的に、こうして作ったクライアントは、たいてい専用アプリがすでにもっとうまくやることの、薄い再実装です。完成度を手放して、統合と組み合わせやすさを得る取引なのです。
だから「Emacs は素晴らしい OS だが、まともなエディタだけが欠けている」という古い冗談が残した緊張は、いまも生きています。ただし、このエッセイはその冗談をかわします。Emacs を OS ではなく汎用クライアントと呼べば、「何でもできる」という魅力と、「どれ一つとして最良ではない」というコストが、同じ息で説明できるのです。このモデルは、すでに Emacs の中で暮らす人にとって強力です。そうでない人にとっては、薄いクライアントを手ずから組み立てる楽しさが、まさにそのままコストでもあります。
おわりに
このエッセイの本当の貢献は、新しい機能ではなく、正確なフレーミングです。「Emacs は OS だ」という緩いミームを、「Emacs の中では、すべてがサービスのように見える」という検証可能な主張へと変えます。そしてその主張を、コードで裏づけます。67 行の天気クライアント、9 行のシェルラッパーです。
私が付け加えたいのは、釣り合いです。このレンズは、魅力と同じだけコストも説明します。ブロッキングな同期呼び出し、自分で握らねばならない配管、専用アプリに比べて低い完成度。著者の結びの一文のとおり、この能力は、その機会を見抜く利用者にとって魅力的です。私はそこに一行を足します。その機会を取った瞬間、完成度と組み合わせやすさのあいだの、古い取引も一緒に引き受けるのだ、と。
参考資料
현재 단락 (1/26)
Charles Choi 氏のエッセイ「In Emacs, Everything Looks Like a Service」が、最近 Hacker News で話題になりました。興味深いのは、この文章...