Erlang/OTP 29.0 が公開されました。
ひとことで言うと、「新機能もあるけど、今回は安全性と堅牢性をかなり真面目に底上げした版」という印象です。Erlangは昔から、止まらない通信システムや分散システムで強い言語として知られていますが、今回のアップデートはその“実戦向け”な性格がさらに濃くなっています。
-unsafe 属性が追加され、危険な関数を明示しやすくなったio_ansi で ANSI カラーや装飾を出しやすくなったct_doctest でドキュメント中のコード例をテストできるis_integer/3、multi-valued comprehensions など言語機能も拡張Erlang/OTP は、チャット、通信、金融、分散処理のような「落ちないことが大事」な領域でよく使われます。
だから新機能だけでなく、危険な使い方を減らす方向の変更がかなり重要です。
今回のリリースで目立つのは、派手な新構文よりも「事故を起こしにくくする」ための改善です。これは地味に見えて、実運用ではかなり効くやつです。個人的には、こういう改善がメジャーリリースで入るのはすごくErlangらしいと思います。目立つ花火より、土台を固める感じですね。
-unsafe 属性と「危険な関数」の可視化Erlang/OTP 29 では、-unsafe 属性で「この関数は unsafe です」と明示できるようになりました。
ここでいう unsafe は「絶対にダメ」というより、呼び出すと危険がある、または注意が必要というニュアンスです。
さらにコンパイラは、Erlang/OTP が「常に unsafe だと分かっている関数」への呼び出しにデフォルトで警告を出します。
これはかなり実用的です。古いコードや大きなコードベースだと、「動くけど危ない」ものが埋もれがちだからです。
加えて xref で unsafe な関数呼び出しや、ドキュメントが不足している関数を探せるようになりました。
xref はコードの依存関係や参照を調べるツールで、ざっくり言えば「静的解析の便利屋」です。こういう道具が強くなるのは、チーム開発ではありがたい話です。
今回いちばん「おっ」と思う変更のひとつがこれです。
SSH daemon は、shell と exec services をデフォルトで無効化するようになりました。
つまり、認証したユーザーが勝手に Erlang コードを実行できないように、初期状態が守り寄りになっています。
これはまさに “secure by default” の考え方です。
初期設定のままでも事故りにくくする、という発想ですね。実際、システムは「設定した人が分かっている前提」で作られがちですが、現場ではその前提が崩れることも多いです。だからデフォルトを堅くするのはかなり重要だと思います。
SSH daemon 起動時に、SFTP subsystem もデフォルトでは有効にならなくなりました。
必要な人が明示的に有効化する形になります。
これも同じく、安全側に倒した変更です。便利さより先に「勝手に開けない」を優先しているわけで、実運用ではかなり筋がいい判断だと思います。
SSL と SSH の両方で、x25519mlkem768 や mlkem768x25519-sha256 といった hybrid algorithm がデフォルトの優先候補になりました。
ここでのポイントは、
という組み合わせです。
要するに、「今すぐ量子コンピュータが全部を壊す」話ではないけれど、将来を見据えて先回りしているわけです。
この手の変更は一見すると遠い未来の話に見えますが、プロダクトの寿命が長いシステムほど効いてきます。Erlangの世界はそういう長寿命システムと相性がいいので、かなり自然な進化だと感じます。
EEP-79 に基づく native records が実装されました。
record は、Erlangでよく使われる「複数の値をひとまとめにしたデータ構造」です。これまでの record は tuple ベースでしたが、native records はそれとは少し違う、本当の型として扱われる新しいデータ構造です。
ただし、これはまだ experimental 扱いです。
つまり「使えるけど、今後の変更の可能性もある」という段階です。ここは無理に飛びつくより、試してみて感触を見るくらいがちょうどよさそうです。
is_integer/3新しい guard BIF is_integer/3 が追加されました。
guard は、関数の条件分岐でよく使う「ここではこの値であってほしい」というチェックです。
is_integer(I, 0, 100) のように書けて、整数であることに加えて、範囲内かどうかもまとめて確認できます。
これ、地味ですがかなり便利です。今まで複数の条件を書いていたところが少しスッキリします。
EEP 78 に基づく multi-valued comprehensions もサポートされました。
comprehension は、リストを生成する短い記法です。
例として [-I, I || I <- [1, 2, 3]] は [-1,1,-2,2,-3,3] を作ります。
「1つの入力から複数の値を出す」書き方ができるようになった、というわけです。こういう機能は、短く書けるだけでなく、表現の幅が広がるのがいいですね。
compr_assign で comprehension 内の代入compr_assign feature を有効にすると、comprehension の中で変数を束縛できます。
例:
[H || E <- List, H = erlang:phash2(E), H rem 10 =:= 0]
これは、要素 E からハッシュ値 H を作り、その条件で絞り込むような書き方です。
こういう「途中結果に名前をつけられる」書き方は、長い処理を読みやすくしてくれるので、かなりありがたいと思います。
JIT は、実行時に機械語へ変換して速くする仕組みです。
今回は、複数の little-endian segment を持つ binary のマッチングや生成で、よりよいコードを出すようになりました。
つまり、バイナリを扱う処理が少し得意になった、ということです。Erlang は通信やプロトコル処理で binary を多用するので、こういう改善は結構効きます。
#{K => 42 || K <- List} のように、生成元に依存しない定数値を持つ map comprehension がより効率的にコンパイルされるようになりました。
こういう最適化は派手ではありませんが、実際のコードの速度や負荷にじわっと効きます。
コンパイラ改善は「何が変わったか見えにくいのに、あとでありがたさが分かる」タイプの変更ですね。
今回かなり目立つのが、デフォルトで有効な警告が増えたことです。
これはコードを書く側には少し耳が痛い話ですが、長期的にはたぶん正解です。
catch の使用に警告古くから非推奨だった catch 演算子に警告が出るようになりました。
今は try ... catch を使うのが推奨です。catch に慣れている人には少し不便かもしれませんが、古い書き方を見直すきっかけになります。
例えば:
file:open(File, AllOpts = [write, {encoding,utf8}])
のような書き方に警告が出ます。
これは「式の中で変数を代入して、外でも使う」ようなテクニックですが、読み手からすると少し分かりにくいことがあります。
and / or に警告古い and と or の使用にも警告が出るようになりました。
代わりに別の書き方を使う方向です。古い流儀を段階的に減らしていく流れですね。
{a,B} = {X,Y} より {a=X,B=Y} の方が分かりやすい、というケースに警告が出ます。
これはかなり納得感があります。見た目が少しすっきりするだけでなく、意図が伝わりやすいです。
list(L) の代わりに is_list(L) を使うような古い guard tests については、長年警告が出ていましたが、Erlang/OTP 30 では削除される予定です。
つまり 29 は「移行の猶予期間」でもあります。ここはアップグレードのタイミングでコードを整理しておくべきだと思います。
rand:shuffle/1stdlib には、リストをランダムに並べ替える rand:shuffle/1 と rand:shuffle_s/2 が追加されました。
地味ですが、テストデータの順序を変えたいときや、サンプルをランダム化したいときに便利です。
こういう「そのうち自分でも使いそう」な関数が標準で増えるのは、素直にうれしいですね。小物だけど、毎日の開発体験を少し良くするタイプです。
io_ansi と ct_doctest も面白いio_ansiio_ansi モジュールで、ターミナルに ANSI sequences を出せるようになりました。
ANSI sequences というのは、文字を赤くしたり太字にしたり、ターミナル上で見た目を変えるための命令です。
これにより、色付き出力や簡単なターミナルアプリを作りやすくなります。
Erlangでこういう機能が整ってくると、CLI ツール開発の居心地もよくなりそうです。
ct_doctestct_doctest は、モジュールの docs やドキュメントファイルにあるコード例をテストできるモジュールです。
これはかなり実用的です。ドキュメントの例が動かない、というのは開発者あるあるですが、それを減らせます。
個人的には、この手の機能はもっと広がってほしいと思います。
「書いた説明と動くコードがズレない」ことは、プロジェクトの信頼性に直結しますから。
Erlang/OTP に 32-bit Windows build はもうないとのことです。
影響を受ける人は少数派かもしれませんが、古い環境を使っている場合は要注意です。
.デフォルトのコードパスでは、カレントディレクトリ . が先頭ではなく末尾になりました。
これは挙動に影響することがあるので、スクリプトや古い運用をしている場合は確認しておいたほうがよさそうです。
Erlang/OTP 29.0 は、単なる機能追加ではなく、安全性の強化・古い書き方の整理・将来を見据えた暗号対応がしっかり入ったリリースです。
特に印象的なのは、SSH 周りの「secure by default」化と、量子耐性を意識した hybrid algorithm の採用です。
このあたりは「今すぐ必須」ではないかもしれませんが、長く運用するシステムでは確実に意味が出てくるはずです。
また、言語機能としても native records や comprehension の拡張が入り、Erlang が少しずつ表現力を広げているのも面白いところです。
守りを固めつつ、ちゃんと前に進んでいる。そんなメジャーリリースだと思います。