世界を動かす技術を、日本語で。

エリクサー 1.19

概要

Elixir v1.19は型システムとコンパイル速度を大幅に改善。 型推論と型チェックの範囲が拡張され、バグ発見効率向上。 プロトコルや無名関数の型チェックも強化。 大規模プロジェクトでのコンパイル時間が最大4倍高速化。 Erlang/OTP 28サポートとOpenChain認証も追加。

Elixir v1.19の型システム強化とコンパイル高速化

  • Elixir v1.19 で型システムの大幅な進化。
  • 型推論 (type inference)と 型チェック (type checking)対象の拡張。
    • 無名関数プロトコル の型推論・型チェック対応。
  • 型推論 は、パターン・ガード・戻り値型などすべての構文に適用。
    • モジュール内および標準ライブラリ内の関数呼び出しも考慮。
    • 例: def even?(x) do rem(x, 2) == 0 end の型が integer() -> boolean() と正確に推論。
  • 型推論のトレードオフ
    • 計算コスト増加、表現力の制限、インクリメンタルコンパイルの複雑化、エラー伝播の難しさ。
    • 明示的な型アノテーションがあれば、型推論の影響なし。
  • 今後の予定
    • ガード式の型推論(v1.20以降)。
    • 依存関係の型シグネチャも推論対象に追加予定。

プロトコルディスパッチ・実装の型チェック

  • プロトコルディスパッチ 時にも型チェックが追加。
    • 例: String.Charsプロトコル未実装型を文字列補間に渡すと警告。
      • %Range{}型を"hello #{range}"で補間→警告発生。
  • for内包表記 でも、Enumerableプロトコル未実装データ型で警告。
    • 例: %Date{}をforのジェネレータに→警告発生。

無名関数の型推論・型チェック

  • 無名関数 の型推論・型チェックが可能。
    • 例: fn %{} -> :map end に対し fun.("hello") 実行で型違反警告。
  • 関数キャプチャ (例: &String.to_integer/1)も型伝搬対応。
  • 型システムの精度向上 でバグ検出力増加。

コンパイル高速化

  • 大規模プロジェクト で最大4倍のビルド高速化。
  • モジュールの遅延ロード を導入し、コードサーバーのボトルネック解消。
    • モジュールは必要時にロードする方式に変更。
    • 並列コンパイラがモジュールコンパイル・ロードを統合管理し、ビルドの決定性向上。
  • 注意点
    • コンパイル中にプロセスをspawnして他モジュールを利用する場合は明示的なロードが必要。
    • @on_loadコールバックで他モジュールを利用する場合は@compile {:autoload, true}が必要。
  • 依存関係の並列コンパイル
    • MIX_OS_DEPS_COMPILE_PARTITION_COUNTで依存関係をOSプロセス単位で並列コンパイル。
    • コア数の半分程度の値が最適とされ、最大4倍の速度向上事例も報告。
    • メモリ使用量増加に注意。

Erlang/OTP 28サポート

  • Erlang/OTP 28.1+ を公式サポート。
  • 正規表現の新しい表現方法 に対応。
    • structフィールドのデフォルト値として正規表現が利用不可に。
    • 構造体初期化時には利用可能。
  • escape/1コールバック でASTへのエスケープ方法を制御可能。

OpenChain認証

  • OpenChain準拠 リリースを初導入。
    • Source SBoM をCycloneDX 1.6+およびSPDX 2.3+形式で同梱。
    • 各リリースはSBoMとともに証明書を発行。
    • サプライチェーン要件への対応強化。

まとめ

  • Elixir v1.19 は型システムの進化とビルド高速化で、既存コードのバグ発見効率と開発体験を大幅に向上。
  • Erlang/OTP 28サポートOpenChain認証 など、エコシステム全体の信頼性も向上。

Hackerたちの意見

Elixirの自動型チェックの段階的導入は、プログラミング言語を壊れずに優雅に改善する方法の参考になるね。多くのプログラミング言語はバージョン間で大きな破壊的変更があって、エコシステムが分裂して解決に何年もかかることがあるから。幸いなことに、ホセは2018年からElixirが完成していることをはっきり言ってくれている。言語は安定していて、基盤ももう変わらないんだ。 https://www.youtube.com/watch?v=suOzNeMJXl0 本当に素晴らしい仕事と運営だね。

完全に同意だわ。Elixirのバージョンを常にアップグレードしなきゃってプレッシャーは感じない。変更点を見てると、アップグレードしたくなる便利な機能があることが多いし、無理にアップグレードさせられるときの嫌な感じとは全然違う。

Elixirはまだちょっと荒削りで、快適さが足りない感じ。安定化と目標達成のためのガイドが必要だね。壊れたパッケージや手入れが行き届いてないガイドが多くて、Phoenixエコシステムの変動が激しいから機能しないことも多い。もっと良くなる可能性はあるけど、すべてのもの™がキュレーションされて、わかりやすいドキュメントが必要だよ。みんながLiveViewsやコンポーネントシステムを使いたいわけじゃないし、他のツールや技術との互換性の学習曲線はまだまだ急すぎる。Python 3は2の問題を解決するために本当に必要だったから、2が3になったんだ。彼らはかなりうまくやったし、Goに似た感じで自動更新ツールや互換性のあるレイヤーを持っていた。でも、すべてがスムーズにいったわけじゃなくて、いくつかのスピードバンプや壊れた部分もあった。一方で、Ruby 3は型を別ファイルにしてツールの断片化を進める方向に行っちゃった。文字列リテラルの動作を変えるためにボイラープレートを選ばなきゃいけないのも問題だし、gemの署名は存在するけどオプションで、中央管理されてなくてあまり使われてない。Ruby Centralの人たちがShopifyの言うことを聞いて、いくつかのgemを実質的に盗んだって話もある。追記: 数年前、柴田宏が理由もなくGHのRuby貢献から僕をブロックしたことがあって、それがすごく攻撃的で不当で突然だったように感じた。だから、rubygemsリポジトリの断片化のドラマは、礼儀や公正さが欠けた権力の乱用の自然な結末に見える。今はRustやTS、他の言語があるから、Rubyにはあまり関わりたくない。誰か一人やグループが自分たちが他の誰よりも優れていると信じると、対立はほぼ確実に避けられない。どんなに「良い」プラットフォームでも、無秩序な行動による悪いガバナンスはそれを台無しにする。PSA: 好奇心があって協力的で、成熟した対立解決スキルを持つ人を探すのがいいよ。深く考えて慎重に、言語ツールのデザインを現実世界で実験するのは、永続的でひどい選択を強いる前に良いアイデア™だと思う。PSA: 正直で思慮深く、明確に変更を事前に伝えて、すべてのユーザーにとって最小限の痛みを与えるようにするのが大事だよ。正直、Phoenix/Elixir/OTPをもっと使いやすく、完成度を高め、表現力豊かに、生産性を上げ、テストしやすく、パフォーマンスを向上させて、学生や趣味の人、スタートアップ、大企業、ウェブや非ウェブ、大データ、AI関連のことをする人たちにとって安全で使いやすい選択肢になることを願ってる。 https://livebook.dev のアプリは、Elixirのワークブックをデスクトップに持ってきてくれるよ。 https://exercism.org/tracks/elixir

うん、アップグレードするたびに(2017年からElixirを本番で使ってるけど)、思ったよりスムーズにいってるよ。Erlang/OTPのアップグレードは互換性の面でちょっと問題があることが多いから、最新のElixirを使ってるけど、Erlang/OTPは一つ前のバージョンを待ってる感じ。数ヶ月待って、すべての不具合が解消されるのを見てる。

プログラミング言語のバージョン間で大きな破壊的変更がある例はたくさんあるけど、思いつくのは2つだけ:Python 3とPerl 6。その2つはかなりトラウマだったから、もっと多く感じるのも無理はないよね。

depsのコンパイルについてのデータポイントだけど、小さなPhoenixアプリでほぼ標準のPhoenix depsを使った場合: MIX_OS_DEPS_COMPILE_PARTITION_COUNT=1 mix deps.compile 32.30s user 7.23s system 320% cpu 12.336 total MIX_OS_DEPS_COMPILE_PARTITION_COUNT=5 mix deps.compile 0.37s user 0.49s system 12% cpu 6.970 total MIX_OS_DEPS_COMPILE_PARTITION_COUNT=10 mix deps.compile 0.38s user 0.50s system 12% cpu 7.236 total マシンはMac M1 Maxで、各実行の間にrm -rf _buildをしてる。

ダウンボートしてる人、なんでこのリリースの機能のベンチマークがダウンボートされる価値があるのかコメントしてくれない?

Elixirの標準ライブラリのdynamic()を使って、アドホックなレポートをコンパイルするためのアプリケーション特有の型推論。boolean() > integer() > boolean()

Elixirは着実に素晴らしい機能や改善をリリースし続けてる。驚くほどよく設計された言語で、クリエイターたちも開発にしっかりしたアプローチを持ってる。日常的にElixirを使えないのが残念だな。

仕事を辞めて、Elixirを使うためだけに会社を始めたよ。

Elixirはまだ混乱してる。言語自体じゃなくて、エコシステムやツール、哲学がね。動的なのか静的なのか?コンパイルされてるのか?もしされてないなら、なぜ異なるファイル拡張子を持つElixirスクリプトがあるの?BEAMを使ってて、エッジケースにぶつかったらErlangを知っておく必要があるなら、どうしてErlangを学ばないの?もし監視ツリーのおかげで「正しい方法」で並行性を解決するなら、なぜPythonのライブラリを使わないの?それもアクターモデルを実装していて、Pythonのコードを「正しい方法」で並行にできるのに。Elixirがどのニッチなアプリケーションをターゲットにしているのか、そしてどこで優れているのかが全然わからない。

もし監視ツリーのおかげで「正しい方法」で並行性を解決できるなら、なぜアクターモデルを実装しているPythonのライブラリを使わないの?Pythonのコードも「正しい方法」で並行性を持たせられるよ。Pythonについてはあまり詳しくないけど、イミュータブルな変数はOTP(Elixir(とErlang)の基盤となるプラットフォーム)の多くの機能にとって重要な前提条件なんだ。

なんでみんなオレンジソーダを飲むのか理解できない。オレンジ味が欲しいなら、オレンジを食べればいいじゃん!泡が欲しいなら、炭酸水を飲めばいいのに!.exは後で実行するためのbeamファイルにコンパイルされるし、.exsはメモリにコンパイルされる。Elixirを使うのにErlangを知ってる必要はないよ。数年使ってるけど、Erlangを書く必要は一度もなかった。

PythonにはGILがあって可変だから、並行性が不可能でエラーが起きやすい。ElixirにはGILがなくて、イミュータブルなんだ。

これらは意外と具体的な質問で、実際に答えられるよ! 1. ダイナミック 2. コンパイルされる 3. Elixirスクリプトは、Elixirコードが書かれたファイルで、すぐにコンパイルして実行される 4. 7年間Elixirを書いてるけど、Erlangはほとんど知らない。バグをOTPチームにElixirで再現して提出したこともあるけど、彼らは気さくだよ。 5. プリエンプティブスケジューラ、イミュータブルデータ

最近の数ヶ月で、Gleamがすごく好きになったよ。Elixirに型システムができたのも嬉しいし、前に試したときはそれが大きなネックだったのを覚えてる。またチャンスをあげたいけど、TypeScriptみたいに見た目は型付きだけど、多くのライブラリやパッケージでは型がダイナミック/anyってことが心配なんだ。俺の不安は正当なものかな?ちなみに、Beamはすごいよね。

GleamはOTPとBEAMの素晴らしさをフルに活かせないけど、Elixirはできるよ。

そうだね、Gleam。JVM上のKotlinもかなり似てるし、必要ならJSにコンパイルもできるよ。

Elixirはプログラミングしてないけど、ファンなんだ。Rubyのファンだったのは、その実用性と主観的な美しさのおかげ。でも、タイプシステムにハマってしまった。今はElixirにもタイプシステムがあるし、Rubyにもあるよね… それに、Kotlinも使ってるけど、文法的にはかなり「タイプされたRuby」って感じ。

Kotlinは、まさに私たちがずっと求めていたjrubyに近いね。