Mozillaでの10年、最短ではないキャリアと「実はすごい」Web(@yusuktan)のトップ画像

Mozillaでの10年、最短ではないキャリアと「実はすごい」Web(@yusuktan)

投稿日時:
maguroのアイコン

Deno Land Inc. / ソフトウェアエンジニア

maguro

Xアカウントリンク
「あの人も読んでる」略して「も読」。さまざまな寄稿者が最近気になった情報や話題をシェアする企画です。他のテックな人たちがどんな情報を追っているのか、ちょっと覗いてみませんか?

みなさんこんにちは。

「あの人も読んでる」、第21回目の投稿です。maguro(X @yusuktan)がお届けします。

今回紹介するのは、Mozillaで10年間働いてきたRyan Huntさんによる振り返り、「Just Keep At It: A Decade at Mozilla」です。

希望通りに進まなかったキャリアがWebAssemblyの仕事へつながったことと、複雑で不格好に見えていたWebを、ブラウザ開発の内側から評価するようになったことが書かれています。
希望通りに進まなかったキャリアも、複雑さを抱えたWebも、あとから振り返ると違う姿に見えてきます。

一度は届かなかったコンパイラの仕事

Huntさんは2016年、Rustに興味を持ってMozillaのインターンへ応募しました。
GraphicsチームとJavaScriptエンジンSpiderMonkeyのポジションを受け、採用されたのは第一希望ではなかったGraphicsチームでした。SpiderMonkeyのポジションは自分でも勝ち目が薄い、と分かっていたようです。

3年後にWebAssemblyチームの募集があり、インターン時代には届かなかったSpiderMonkeyの領域へもう一度応募します。
コンパイラは余暇に独学していた程度でしたが、今度は見事採用。Graphicsチームでの経験もあり、膨大なコードベースを探索するのは得意になっていたものの、それはSpiderMonkeyに携わる上ではあって当たり前のもの。コンパイラの理論と実践を数多く学ばなければなりませんでした。しかし今ではWebAssembly Community GroupにおけるMozillaの代表も担うようになりました。

インターンのときは「勝ち目が薄い」と感じていたコンパイラのポジション。そこに結局行き着いて、そしてそれがキャリアの中で最もやりがいのある仕事になったというのが、なんとも奇妙だ、と綴っています。

分からないまま続けた経験

Huntさんの歩みを読んで、僕自身のこれまでにも重なるところがあると感じました。

僕もRustを学び始めた当時、CやC++をほとんど触ったことがありませんでした。むしろ大学で初めて学んだプログラミング言語であるCには、トラウマのような感情を抱いていました。
そんな中、苦しみながらも競技プログラミングの問題をRustで解き、頻出するデータ構造を実装したり自分専用のライブラリ化したりしながら、Rustの独特の所有権や借用の考え方に少しずつ慣れていきました。
この経験が、その後Rust製のOSSにコントリビュートするときに役立っていきます。

その後は、仕事を続けながらジョージア工科大学のオンライン大学院に通い、コンパイラやコンピュータアーキテクチャ、分散システムなどを学びました。仕事でやっている一般的なWebバックエンド開発ではあまり意識しなくてもいいような低レイヤーのトピックを、好奇心のままに履修しました。
難しすぎる課題に心が折れそうになることもありましたが、粘り強くログとにらめっこしながら仮説検証を繰り返したり、教科書や論文などを参照してそれをコードに落とし込む作業をした経験は、今でも活きているなと感じています[1]

競技プログラミング、Rust、大学院、Denoと、これまでの僕のキャリアはきれいな一本道ではありません。ただ、どれもそのときに自分自身がやりたくて選んだ道です。
一見あまり関係ないように思える2つの経験が、あとから振り返ってみると思わぬところで間接的に役立っている、ということは往々にしてあります[2]

Huntさんも、道筋そのものより、「慣れない領域で分からない状態が続いても、挑戦し続けること」が自分を成功に導いた、と振り返り、"Just keep at it"(「諦めずに頑張り続ける」)という表現で教訓を伝えています。

Webは本当に不格好なのか

Mozillaでの10年間を経て、HuntさんのWebに対する評価も大きく変わりました。

Mozillaへ入った当初、HuntさんはWebそのものにあまり興味がなく、POSIXにGPU APIを足したようなものになればよいと考えていたそうです。
Webには長い歴史の中で追加されたAPIや仕様が大量にあり、似た方法がいくつも残り、過去との互換性のために不思議な挙動も維持されています。
もっと小さく一貫した仕組みにつくり直せるのではないか、と考えるのはある意味自然です。

Huntさんはブラウザ開発を続けるうちに、その見方を変えました。

昔のページを壊さない後方互換性、複数の企業やコミュニティで決めるオープン標準、信頼できないリンクを開ける安全性などを、Webは同時に成立させようとしています。

歴史的な事情で残った複雑さや、今から直したい部分もあります。
一方で、不格好な仕様の裏に、壊してはいけないサイトや、ブラウザ実装者の合意や、利用者が当然だと思っている挙動が隠れていることもあります。

これらの制約を抱えながらも、オープンな形で着実に進化し続けるWebを、Huntさんは "The web is actually great" (Webは実はすごい)と評価しています。

JavaScriptを使う側から、仕様を見る側へ

僕自身も、プログラミングを始めて間もない頃、JavaScriptについて勉強していく中で、「この書き方は古くてトラップがあるので推奨されない」「初学者がハマりがちなJavaScriptの奇妙な挙動◯◯選!」などを知って、なぜJavaScriptはこんなに混沌としているんだ?と感じたことがあるのを覚えています。

僕の中でこの見方が変わったきっかけの一つは、JavaScriptとTypeScriptを仕事で使うようになり、ECMAScriptの仕様や新しいAPIが決まる過程を見るようになったことです。

以前、「Why I love JavaScript」というCosenseのページに、JavaScriptのエコシステムを好きな理由を書き出したことがあります。とある技術コミュニティ[3]のイベント後の懇親会で「JavaScriptはカオスだ」という話題になり、そこで(酔っ払いながら)話した内容をまとめたものです。軽く内容を引用してみます。

JavaScriptにはV8JavaScriptCoreSpiderMonkeyといった主要なエンジンがあり、QuickJSのような小規模な実装もあります。
ブラウザの外にもNode.jsDenoBunCloudflare Workersなど、実行環境がいくつもあります。

1つの実装が事実上の仕様になる言語やエコシステムも多い中で、JavaScriptでは共通のECMAScript仕様が中心にあり、各エンジンがそれぞれ実装します。

新しい言語機能はTC39で提案され、実装者や利用者からのフィードバックを受けながら段階を進みます。
1社が自分たちの都合だけで決めるのではなく、異なる立場の人たちが議論し、合意できる範囲を探していきます。

さらに、ECMAScriptにはtest262、より広いWeb APIにはWeb Platform Tests(WPT)という共通のテストスイートがあり、別々につくられた実装が同じ振る舞いを目指せます。

仕様があり、複数の実装があり、テストで相互運用性を確かめ、その結果がまた仕様へ返っていく。
この循環を知ってから、複数のブラウザやランタイムが存在することを、単なる面倒さとは感じなくなりました。

他の言語やライブラリなら、よい設計へ移るための破壊的変更がメジャーバージョンアップとして受け入れられることがあります。
しかし、Webでは、大昔に書かれたコードも動き続けることが原則です。新しい機能を入れたいからといって、既存のページをまとめて移行してもらうことはできません。
その厳しい縛りの中で、それでも言語やWeb APIは少しずつ進化しています。

Webの後方互換性をよく表す例が、ブラウザのUser-Agent文字列です。
Rui Ueyamaさんによるnote記事「ソフトウェアの互換性と僕らのUser-Agent文字列問題」でもこの例が取り上げられています。

現在の主要なブラウザは、User-Agentの先頭でいずれも Mozilla/5.0 と名乗ります。Web黎明期、多くのWebサイトが Mozilla/5.0 を含まないリクエストを古いブラウザからのものと判定し、簡素なページを返していたためです。
後から登場したブラウザは、正しく自分の名前だけを名乗るよりも、既存のWebサイトで正しく扱われることを優先しました。結果として現在でもUser-Agentは奇妙な文字列となっています。

整理された後発言語は、過去の失敗を見てから設計できるという意味で、いわば「後出しじゃんけん」ができます。
JavaScriptとWebは「先出しじゃんけん」をしてしまった側なのに、過去を抱えたまま新しい機能を貪欲に取り込んでいます。

「Webを壊さず、技術の発展も止めない」という人たちの営みを知ったことが、僕のWebに対する印象を大きく変えました。

Denoが引き受けてきた複雑さ

僕が開発に関わっているDenoも、既存の仕組みを見直すところから始まりました。

Node.jsをつくったRyan Dahlは、2018年の講演「10 Things I Regret About Node.js」で、node_modulesやnpmへの依存、デフォルトで広い権限を持つことなど、Node.jsの設計上の後悔を挙げて、「だから0からつくり直す」ということを宣言しています。そうして生まれたのがDenoです。

初期のDenoは、URLからモジュールを読み込み、ファイルやネットワークへのアクセスには明示的な許可を求め、package.jsonnode_modulesを前提としませんでした。

当初の僕は、Denoがつくろうとしていた「美しい」世界に惹かれ、共感していました。
Node.jsの歴史的な事情をいったん脇へ置き、Web標準に近いAPIと明示的な権限管理を備えた環境をつくる。それが広がれば、JavaScriptやTypeScriptを使う体験をもっと分かりやすくできると思っていました。

しかし、そのような理想の世界の実現に向けて開発を進めていく中で、現実の課題も見えてきました。多くの人に使ってもらうには、既存のnpmパッケージやNode.js向けツールを無視できません。
package.jsonを読み、同じようにモジュールを解決し、ネイティブアドオンや各種ツールが期待する細かな挙動にも合わせる必要があります。

美しい設計を見せるだけでは、すでにNode.jsで仕事をしている多くの人には届きません。
新しいランタイムを試すのに、利用中のパッケージやビルドツールや開発手順をすべて入れ替えてもらう。その移行コストを受け入れてもらうには、大きな壁がありました。

実際、Deno 2ではNode.jsとnpmとの互換性を強化し、Node.jsやnpmのプロジェクトをそのままDenoでも動かせるようにすることが、Deno開発チームの最優先事項の一つになりました。
その方針は、当記事執筆時の最新バージョンであるDeno 2.9でも継続しています。

一言で言ってしまうと、当初考えていた理想の世界からは少し離れて、既存のエコシステムへの歩み寄りをしている形になります。

しかし、僕はこの変化を最初の理想からの後退とは考えていません。
パーミッションモデルなどDenoの良さを残しながら、利用者が持っているコードや知識を捨てずに使えるようにすることも、ランタイムが解くべき問題でした。
外からは余計に見えた複雑さの中に、長年の利用者が必要としてきたものも混ざっていたのです。

既存エコシステムを取り込みながら、Denoらしい強みも損なわない。
どちらかを諦めれば話は簡単ですが、その両方を妥協せずに進めるのはとても難しい仕事です。しかしその難しさの中に価値があります。

Webに対する見方が変わったのも、この経験があったからです。
何十年分ものコンテンツと多数の実装を抱えたまま改善を続けるWebを、以前よりずっとおもしろいプラットフォームだと感じるようになりました。

おわりに

遠回りに見えた経験も、不格好に見えた技術も、時間が経って初めて分かることがあります。

僕自身も、Rustや大学院やDenoを選んだ時点で、それが今の仕事へどうつながるかを見通していたわけではありません。でも、今振り返ってみると、最短ではなかったものの、無駄な道のりでもなかったな、と思っています。

また、Denoで互換性の難しさに向き合った経験は、今度はWebの複雑さを見る目を変えました。
今では、昔から使われている言語やライブラリに対して、ただ「古臭いからだめだ」と断じるのではなく、その時代の制約や、互換性を保ちながら進化してきた過程を知り、そしてリスペクトしたい。そう思うようになりました。温故知新ですね。

また次回、おすすめコンテンツを紹介していきます。お楽しみに!

執筆者へのお便り

maguroさんの「も読」過去記事

脚注
  1. 今や、AIのおかげで自分の手でコードを書くことが少なくなりましたが、それでも依然として、粘り強くやった泥臭い経験は血肉となり、自分を助けてくれていると感じます。

  2. いわゆるSteve Jobsの伝説のスピーチ中に出てくる "connecting the dots"(「『将来役に立つか?』と考えず、ただ興味を持って取り組んだこと(点)が現在の礎(線)になっている」)という、僕が強く共感している考え方です。

  3. funabashi.dev という千葉・船橋を中心にしたITエンジニアコミュニティです。

43
43