
2026/10/06 17:08
Gleam はもはや Erlang ソースコードにはコンパイルしません。
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
Gleam バージョン 1.19.0 は、Erlang コードジェネレータの完全な書き換えによる大きなマイルストーンをマークします。コードジェネレータは現在、ソーステキストではなく抽象形式を出力するようになっています。このアーキテクチャ変更により、生成されたコードをバイナリ外部項形式から直接読み込むため、Erlang コンパイラーの前側プロセスをスキップでき、BEAM クラッシュレポートとスタックトレースでの正確な行番号を確保し、コンパイルパフォーマンスが劇的に向上しました。BEAM バイトコードを直接生成しないことで、進化している VM リリースとの互換性を維持するコストを回避し、Elixir の抽象形式使用という実績あるアプローチを活用しています。ベンチマークの結果、Erlang ターゲットでは v1.17.0 比で大幅な速度向上が見られ、開発中のインクリメンタルビルドは特に高速です。また、Go、Java、Elixir、Rust、C# のような言語との比較においても、架空の 100 モジュールテストにおいて Gleam は素早くコンパイルされます。追加の最適化としては、短いリストに対する直接コンストラクターコードの生成を行うスマートなリスト処理と、JavaScript における決定木ベースの割り当て最適化が含まれます。このリリースでは、開発者ツールの強化も行われており、言語サーバーへの完全なラベルサポート、API オーバーロードを通じた TypeScript タイプ情報の改善された保持、ビルドコマンドの改善(
--no-dev フラグ、パッケージ情報に対する stdout 出力オプション、.app リソースファイルの生成)が含まれます。エラー報告もより精密となり、git メージコンフリクト、無効なレコード更新、手続き演算子、パターン不一致、プライベート型のアクセスに対して新しい特定のエラーが追加されました。これらの変更は、ユーザーが複雑なコンパイラー内部を管理する必要をなくしながら、高速なフィードバックループ、堅牢なツールング、優れた開発者体験を提供します。本文
Gleam 1.19.0 リリース:新機能とパフォーマンスの劇的向上
Gleam は Erlang 仮想マシン (VM) および JavaScript ランタイム向けに設計された、型安全かつスケーラブルな言語です。 本日公開された Gleam v1.19.0 の主要な新機能と改善点を整理しました。
1. 新しいコンパイルターゲット(Erlang アブストラクト・フォーム採用)
直近の数ヶ月間で Giacomo Cavalieri が Erlang コードジェネレータを完全に書き換えました。
- 出力形式の変更: 以前は Gleam から Erlang のソースコードを生成しておりましたが、現在は Erlang アブストラクト・フォーム (Abstract Forms) という中間表現 (IR) を生成します。
- これは Erlang コンパイラーが内部で使用する木構造であり、外部項形式 (External Term Format) でバイナリエンコードされています。
- 従来の「フロントハーフ(トークナイザーやパーサーの実行)」をスキップして直接読み込むことが可能です。
メリット
- コンパイラのパフォーマンス向上: Erlang 上での Gleam プロジェクトのビルド時間を大幅に短縮しました。
- メタデータの精度向上:
- ランタイムへの位置情報(行番号など)が、元の Gleam ソースコードに対して正確になりました。
- BEAM クラッシュレポートやスタックトレースにおいて、以前不正確だった「最近接の関数表示」を解消し、完全なエラー情報が得られるようになりました。
- 将来的には
などのデバッガーでのフルサポートが可能になる可能性がありますが、現状では検討中です。edb
- コード品質の向上: 最も古く安定していた部分でしたが、最新の実装へ更新され、コンパイラ全体のハードルを一段引き上げました。
- 「トランスパイラー」という言葉が使われる必要がなくなりました。
2. コンパイル速度の劇的改善 (ベンチマーク)
ベンチマークデータは
langcompilebench (José Valim) を基盤としています。
- 比較対象: 1.18.0 (中間表現導入前) から 1.19.0 (新機能実装後)。
- キャッシュなしの完全リビルド(クリーンビルド)での比較。
ベンチマーク結果(Gleam v1.19 vs v1.17)
- Gleam v1.19:劇的な速度向上が見られます。
- インクリメンタルビルド: 開発プロセスではキャッシュが利用されるため、実際の速度はさらに高速化されます。
他言語との比較 (100 モジュール「hello world」コンパイル時間)
Gleam は以下の言語と比較し、非常に高速であることが示唆されました:
- Gleam (JavaScript)
- Gleam (Erlang)
- Go
- Erlang
- Java
- Elixir
- Elm
- Rust
- C#
- TypeScript
注意: 言語ごとのコンパイルコストはコードの多様性によります。あくまで一つの目安と捉えてください。
3. なぜ BEAM バイトコードを直接ターゲットにしないのか?
BEAM バイトコードジェネレータを作成して Erlang コンパイラーを凌駕しなかった理由です。
- 不変性の欠如: ベアメ・バイトコードは VM のアップデート(機能追加/削除)により絶えず変化します。これに対応し続けるのは現実的ではありません。
- 最適化の再現: 数十年来の実装された既存のすべての最適化をゼロから実装するのは困難です。
- コスト対効果: Gleam はスポンサーシップで支えられており、リソースを最も効率的かつ持続可能な方法で活用する必要があります。現状の**「Erlang アブストラクト・フォームへのコンパイル」がスイートスポット**にあります。
- コミュニティとの調和: Elixir も同様にアブストラクト・フォーム経由でコンパイルしており、Gleam でも十分です。
4. JavaScript ターゲットへの改善
JavaScript コンパイルにおける制御構造やデータ構造の最適化を行いました。
デシジョンツリーの割り当て最適化
- 仕組み: John Downey が分治法 (divide-and-conquer) を用い、ネストされた
文を単一の条件に畳み込みました。if - 結果: ブランチの数を減らし、JavaScript エンジンによる最適化がしやすくしました。
- 以前: ネストされた深い
文(コード量が膨大)。if - 現在: 扁平で簡潔な論理式。
- 効果: コードバンドルのサイズ変化は小さいですが、実行時の効率は大幅に向上しました。
- 以前: ネストされた深い
リストリテラルの最適化
- 背景: Gleam の不変リストは JavaScript の可変アレイとは異なります。通常、リストリテラルは
関数を呼び出して変換されます。arrayToList - 改善点: コンパイラーが短いリストリテラルに対して、アレイ構築を行わずに直接コードを実行するようになりました。
- 以前:
const numbers = arrayToList([1, 2, 3]) - 現在:
const numbers = prepend(1, prepend(2, prepend(3, empty)))
- 以前:
- 効果: 特に多くの短いリストを使用するプロジェクト(例:Lustre ライブラリ)でパフォーマンス向上が見られました。
5. TypeScript API オーバーロード
Gleam コンパイラーは、型情報を保持しつつ TypeScript 宣言ファイルを生成します。
- 問題点: 単一の関数定義では、コンテナ型の型パラメータ (
) がnumber
に汎用化され、型情報の損失を引き起こす可能性があります。unknown - 解決策: Giacomo Cavalieri がAPI オーバーロードを追加しました。
- 具体的な型(
)を持つ場合は型情報を保持した関数定義を生成。Box$<I> - 汎用的な場合 (
) を別に定義。any
- 具体的な型(
- 結果: 型情報の損失を防ぎ、より安全な TypeScript 開発が可能になりました。
6. コマンドラインツールの改善 (Elixir/Erlang統合)
gleam 実行ファイルの機能向上により、Elixir の Mix や Erlang の rebar3 での Gleam コード利用が容易になりました。
ファイルの自動生成: コンパイル時に自動的に必要な.app
リソースファイルを生成します。.app- 開発依存スキップ:
コマンドにcompile-package
フラグを追加し、ビルド対象から dev_dependencies を除外できます。--no-dev - 出力フォーマットの多様化:
/export package-information
: 情報を標準出力 (stdout) に出力。export package-interface
/export javascript-prelude
: ファイルへの書き込みをサポート。export typescript-prelude
7. IDE サポートとツール機能の追加
- ラベル対応: Alistair Smith らにより、言語サーバープロトコルにおけるフィールドと引数のラベルに対する完全サポートが実装されました(定義移動、参照検索、名前変更など)。
- ブラウザ内フォーマット: John Downey が
関数を追加。Web ブラウザ内で Gleam コードのフォーマットを実行可能にしました(近々プレイグラウンドへの導入予定)。format_source
8. エラーメッセージの改善
Gleam のデバッグを容易にするための細やかな対応です。
- 構文エラーの詳細化: Git マージコンフリクトマーカや、存在しない演算子 (
,+=
等) に対する明確なエラーを追加。*= - パターンマッチングの補助: Java などで有効な構文だが Gleam では無効な場合のヘルプメッセージを追加。
- プライベート型の表示: 同一パッケージ内のモジュールがプライベート型を使用しようとした際、存在はするが非公開であることを明記したコンテキストを提供(外部依存パッケージへの漏洩防止)。
- 型エイリアスのカスケードエラー対策: 無効な型エイリアス定義による連鎖エラーを解消。
9. サポートのお願い
Gleam は企業所有ではなく、主に月額 5 ドル〜20 ドルの寄付によって支えられています。
- プロジェクトまたはコアチームメンバーへの支援をご検討ください。
- 詳細は変更ログやスポンサーページを参照してください。