以下の記事はAIを使って動画を元に生成された記事となります。
元動画はクリエイティブ・コモンズ著作権表示必須ライセンスです。
Crystal 1.0 リリース 5周年 AMA レポート
元動画: Crystal 1.0 anniversary – 5 years AMA(YouTube) 収録時間: 約1時間30分
ライセンス: クリエイティブ・コモンズ著作権表示必須ライセンス(再利用を許可する)
以下はAIを用いた書き起こしと要約です。
1. Crystal 1.0 の意義——振り返り
何が変わり、何が変わらなかったか
Crystal 1.0 は機能的には「大きなリリース」ではなかった。基本的には 0.36 の安定版という位置づけで、重複機能の削除と小さな機能追加が二つほどあった程度だ。しかし「1.0」という名称が持つ意味は技術的な変更とはまったく別の次元で重要だった。
後方互換性の保証。 1.x 系のすべてのバージョンで Crystal コードが動き続けることを保証した。この5年間、バグ修正で稀に壊れることはあったものの、互換性はほぼ維持されてきた。
予測可能なリリース周期の確立。 「次のリリースはいつか、機能は十分か」と悩む必要がなくなり、3ヶ月ごとのマイナーリリースという安定したサイクルが生まれた。継続的な改善という文化が根付いた。
スコープの明確化。 1.0 前に「これはやらない」と決めたものがある。Windows サポート、デバッガの改善、マルチスレッドはすべて「1.0 後に回す」と宣言された。これは逃げではなく、1.0 を確実に出荷するための戦略的判断だった。そして AMA の時点で、それらはすべて実現または進行中だった。
1.0 以降の5年間の主な成果
1.0 後に回すと言っていたものが、この5年でほぼ揃った。
- Windows サポート: Tier 1 昇格が目前。2〜3リリース前から基本的に動作している。
- マルチスレッド: メインスポンサー企業の代表曰く「ソフトウェアを次のレベルへ引き上げた最大の改善」。
- Arm64 ネイティブサポート: Apple Silicon ユーザーにとって必須の対応が完了。
- インタープリタ: 当初まったく想定していなかったが登場した。LLVM によるハードウェアターゲットの拡張も進んだ。
- Android・Solaris サポート: Linux/macOS/BSD とは異なる特性への対応で実装のポータビリティが試された。
- autocast(自動キャスト)・128bit 整数: 言語機能として追加。
- lifetime event loop: 従来の libevent より効率的な実装に置き換わった。
- コンパイラのバグ多数修正、ツーリング全般の改善。
2. 並行処理——Execution Context の現状
なぜ Fiber だけでは足りないのか
Fiber は I/O 待ちなど OS を介して何かを待つ場面では非常に効率的だ。スレッドより軽量で、そのために存在する。しかし「1つの Fiber を特定の CPU スレッドに固定したい」「Fiber と実際のスレッドを組み合わせたい」という要求には従来のスケジューラでは答えられなかった。
Execution Context——実装完成、最終調整中
この問いへの答えが新しい Execution Context だ。設計は Kotlin の並行モデルに大きく影響を受けている。コアチームメンバーが中心となって開発し、機能自体は実装済みで、AMA 時点ではメモリ安全性を宣言するために残りのバグを潰している段階だった(プレビューフラグで2〜3リリース前から試せる状態)。
Execution Context は以下の使い方を可能にする:
- デフォルト(Go 方式): 複数スレッドで Fiber を自動スケーリング。意識しなくてよい。
- スレッドへの Fiber の Pin: 特定の Fiber を特定のスレッドに固定し、他の部分をブロックしない。
- スレッドプリエンプションの活用: 複数の Context を起動し、カーネルによるスレッド切り替えを活かした挙動。
特筆すべきはワークスティーリングの実装だ。メインスポンサー企業の実測では、32 コア環境で 32 の Fiber を1つの Parallel Context で動かす方が、複数の独立した並行処理を起動するよりずっと効率的だった。ランタイムに委ねることで自然にスケールする。
3. コンパイル速度——構造的な難しさと現実的なアプローチ
なぜインクリメンタルコンパイルが難しいか
「どこかを変えると、どこでも何かが変わりうる」——これが Crystal の型推論の本質であり、インクリメンタルコンパイルの最大の障壁だ。モジュールに明示的なインターフェイスがなく、グローバル名前空間にすべてのコードが同居するため、標準ライブラリとアプリケーションコードの間に境界を引けない。
「インクリメンタルコンパイル」と「モジュラーコンパイル」は別物だ。インクリメンタルは以前の結果を再利用して差分だけ計算する。モジュラーは独立した単位を識別して個別にビルドする。Crystal の場合、後者の方がより現実的な目標として語られた。
現在やっていること・やれること
ビットコードキャッシュはすでに導入され大きな改善をもたらした。しかし Union 型のマルチディスパッチがビットコードを大量に無効化するという問題が残る。ビットコードの形を変えることでキャッシュをより有効活用できる可能性がある。
型推論が型注釈を不要にするように「コンパイル単位推論」——「このコードはアプリケーションによって変わらない」と判断して別途コンパイルする仕組み——の可能性も示唆された。言語に妥協を求めるものもあれば、そうでないアプローチもある。
メソッドへの型アノテーション義務付けは一部から提唱されているが、「言語の本質を大きく変える」として慎重な声もある。言語創設者は「失敗に終わっても探索する価値はある。今は出荷のための開発に集中してきたが、探索に時間を使う時期かもしれない」と語った。
4. LSP とツーリング——採用の最大障壁
「50〜90%の人を失う」
コントリビュータは断言した。「TypeScript や C など人気のある言語から来た人がエディタを開いて公式エクステンションをインストールしても、言語サーバーのサポートが全くない、タイピング中にエラーが出ない。最初の体験がとても悪くて、それだけで50〜90%の人を失うと思う」。
これはコアチームにとっても認識の更新を促す発言だった。「日々の開発でこんなに多くの人が言語サーバーを使っているとは知らなかった」という声がコアチームから出た。
なぜ LSP が難しいか
コンパイル速度の問題と根は同じだ。Crystal の設計はプログラムの状態変化を追跡して状態を保持するのを難しくしている。コンパイラは LSP が存在する前に設計された——「今なら間違いなく違う設計にしていた」という言葉が印象的だった。
ツーリング担当のコアチームメンバーは現在の取り組みとして、ソースコードへのセマンティック解析、そして最初からフォールトトレラントに設計されている tree-sitter の活用を挙げた。到達可能性ツールや「このメソッドはどこで呼ばれているか」などの初期ツールはあるが、速さを意識して作られたものではなかった。
コンパイラにメトリクスを埋め込んで使用状況を収集することはオープンソースの精神に反するとして避けている。コミュニティからの声が設計の方向を決める。
5. スレッド安全性——Rust 方式の否定と現実的な代替
「型安全性のためにやったことと同じことをスレッド安全性にもできるか」という問いに対し、元コアチームリードは明確に答えた。
Rust はすでにそれをやっている。型システムで並行安全性を保証している。しかし Rust はその代償として学習コストが高く、型チェッカーと「戦わなければならない」場面が多い。「すべてのメソッドに型アノテーションを追加することに反発する人が、すべての変数に別のシジルを追加することを受け入れるか?」——答えは直感的に No だ。「それはもはや Crystal じゃない」。
現実的な方向として挙がったのはコンパイラ・標準ライブラリ側でのデフォルト安全性の改善と、コードが動いた後でフルセマンティックパスを走らせて並行バグを検出するリンタの開発だ。すべてのバグを捕まえることはできなくても、確実に助けになる。
6. エコシステムと普及——構造的な課題
ライブラリの不足と企業バックアップの欠如
Shard は約 1 万あるが、そのうちアクティブなものがどれだけあるかは不明だ。問題はライブラリの数だけでなく、多くのサービスプロバイダーが「一流言語リスト」に Crystal を含めていないことにある。Java、Rust、JavaScript、TypeScript、Ruby、Go はあっても Crystal はない。結果としてサードパーティの Shard に頼ることになり、必要な API の一部しか実装されていないこともある。
人気のある言語にはすべて強力な企業バックアップがある。大手テック企業に支援される言語と、コミュニティだけで支える Crystal とでは規模が違う。「基本的にはそういう企業のどこかの注目を集める必要がある」という正直な分析が出た。
LLM による補完の可能性
0.x 台の言語に SDK を作る企業はいない——1.0 はその壁を取り除いた。そして今、LLM が新たな補完手段として浮上している。Ruby から Crystal への移植は LLM を使えばかなり簡単だとフォーラムで聞かれる。クライアントライブラリは「LLM が輝けるケース」の一つかもしれない。イディオマティックなコードにはならないかもしれないが、空白を埋める手段になりうる。
標準ライブラリの境界線と DeFacto 標準
標準ライブラリをどこまで広げるかという問題も議論された。Crystal DB は当初標準ライブラリに入れる予定だったが、結果的に別の Shard にしたことで「標準ライブラリ外の DeFacto 標準」になれた。同じ発想で、ロギング API も Crystal 全体で共有できる標準的な方法を目指して設計された。
一方で、crystal-lang や crystal-community に入っていない Shard は信頼を築くのが難しい。設定管理など、良い Shard があってもコミュニティとして「これが私たちの方法だ」と認定することが難しい——コミュニティが小さく、企業よりも個人で構成されているためだ。Web フレームワーク向けの rack 相当の抽象化レイヤーも、標準ライブラリに入れるべきか別 Shard にすべきか結論は出ていない。
7. パッケージ管理——分散型の哲学と現実的な課題
Shards は中央リポジトリを持たない分散型を採用している。RubyGems のような中央リポジトリは、ホスティングコスト・帯域・モデレーション・セキュリティのいたちごっこを生む。Shards v1 から v2 への移行のような破壊的なマイグレーションも不要になる。「パッケージ作者を信頼する」という価値観を体現した設計だ。
しかし現実の課題もある。作者が GitHub の Organization を削除すれば依存関係が消える。ShardBox のようなインデックスがミラーや代替を把握して、アップストリームが利用できないときに代替を提示できれば解決の一助になる——ただし自動的にやるべきではなく、十分信頼できるインデックスが前提だ。
現状ほとんどのパブリック Shard は GitHub にホストされているため、「中央リポジトリがなくても GitHub が落ちたら同じことが起きる」という指摘もあった。実用的な対策として、依存関係を lib フォルダごとリポジトリにチェックインしておくことが紹介された。
8. Ruby コミュニティとの関係
Ruby との類似性は Crystal の採用を助けてきた——メインスポンサー企業も元は Ruby ショップで、Crystal に似ているからこそ乗り換えられた。Crystal は Ruby コミュニティでは他のコミュニティより知られている。
一方で直接統合の難しさも正直に語られた。Ruby はこの数年でパフォーマンスが大きく改善され、以前ほど「Crystal に乗り換える切迫した理由」は少なくなった。ただし Crystal ならではの優位は残る。静的リンクバイナリの配布——Ruby のインストールと依存関係を一緒にパッケージングせずにクライアントツールを配布できる——はその典型だ。
Go や Rust に「速いから」という理由で流れている Ruby 開発者に対して、「Crystal も候補になる」という声も出た。Go や Rust より速いこともある(いつもではないが)、そして Ruby 開発者にとっては構文的に心に近い。
マーケティングについては「得意でない——それはずっとそうだ」と率直な認識が示された。Crystal を使う企業が積極的に発信しなければ、ニッチな言語は採用が細っていくという現実も共有された。
9. Crystal 2.0——いつ来るか、何が変わるか
「まったく別の言語になる」ではなく探索
Crystal 2.0 の具体的な時期は「全くわからない」というのが正直な答えだ。1.0 以降は後方互換性を最優先にしてきたため、破壊的変更のアイデアは蓄積されていない。「破壊するだけの十分な価値がある変更を2〜3個揃えなければならない」という基準が示された。
参考モデルとして Rust の Edition と Haskell の Language Extensions が挙げられた。言語を大きく変えずに、コンパイル単位の扱い・グローバル名前空間・マクロシステム・「すべてが式」の見直しなど、ツーリングや開発者体験の改善につながる変更を探索する段階に入りつつある。
ただし破壊的変更には移行ツールの整備が前提となる。「破壊的変更を前に、ユーザーが対処するための簡単な解決策を提供できなければならない」——ここも Todo リストに追加された。
2.0 では機能の削除もありうるが、多くはない。重複しているものはより良い代替に置き換えてきた。「ツーリングやインクリメンタルコンパイルを可能にするような、言語から何かを取り除くことで到達できる大きな価値がない限り」大きな削除は起きない。
「Crystal は現実の言語になった」
言語創設者はこう語った。「理想の言語という構想は時間とともに確実に変化してきた。今の言語には癖がある。でもすべての現実の言語にはそれがある。癖のない言語は理想の言語だけで、現実の言語ではない。Crystal は現実の言語になった。それは良いことだ——実際に使われていることの証拠だから」。
10. 財政状況と AI の位置づけ
財政:小さいが持続可能な体制
Crystal の財政は 84codes(LavinMQ を開発・運用。2017年から Crystal ユーザーで、1.0 前から本番投入していた)がメインスポンサー。Open Collective の各スポンサー(Place など)と GitHub Sponsors を合わせて、ほぼフルタイムで働く開発者 2 名を維持している。
「Crystal はリスクではなく Competitive advantage」——メインスポンサー企業代表のこの言葉がスポンサーとしての姿勢を端的に表している。大手テック企業に支援される言語とは資金規模が違うが、今の状態を維持するには十分だ。
AI との関係:補完手段として現実的
現在の LLM は Crystal コードの生成が1年前より格段に向上している。静的型付けにより、型が正しいかどうかをチェックしながら素早くイテレーションできるという意味で LLM との相性は悪くない——ただし他の静的型付け言語との差は大きくない。
Crystal のイディオマティックなコードの書き方は他言語とかなり異なることがある(ビジターパターンなど)。LLM がすべてのベストプラクティスを知らないのは当然で、サンプルがない場面もある。「何がイディオムか教えてやれば、LLM はイディオマティックな Crystal コードを書いてくれる」というのが実践的な知見だ。
機械学習のトレーニング言語としての Python の地位は揺るがない。Crystal がその領域に入ろうとする理由はない。AI サービスを利用する側としては Crystal も他言語と同等だ。
GitHub 移行の予定はなし
Issues、Pull Request、CI の移行コストを考えると、現状 GitHub で問題がない以上、他の改善にリソースを使う方が合理的というのがコアチームの判断だ。
まとめ
Crystal 1.0 の5年は、宣言した通りのことをやり遂げた5年だった。Windows 対応、マルチスレッド、Arm64、新しいプラットフォーム——「1.0 後に回す」と言ったものがほぼ揃った。
次の5年の焦点は開発者体験の底上げにある。Execution Context の正式リリース(ワークスティーリング付き並行スケジューラの完成)、Windows Tier 1 昇格、そして長年の懸案である LSP とコンパイル速度の改善——これらが短期の目標だ。
中長期では、コンパイラ基盤の再設計(グローバル名前空間・モジュール境界の整理)が、ツーリング・インクリメンタルコンパイル・LSP すべての土台になりうる。破壊的変更には慎重だが、探索の時期に入りつつある。
「癖のない言語は理想の言語だけで、現実の言語ではない。Crystal は現実の言語になった」——この言葉が今の Crystal を最もよく表している。