ハクソク

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

グリームプログラミング言語

概要

  • Gleamは強力な型システム関数型プログラミングの表現力を持つ言語
  • Erlang仮想マシン上で動作し、高い信頼性スケーラビリティを実現
  • モダンで親しみやすい構文豊富なツール群を提供
  • 他のBEAM言語やJavaScriptとの連携が容易
  • 多様性と包摂性を重視したフレンドリーなコミュニティ

Gleamの特徴と実行環境

  • Gleamは、堅牢な型システム関数型プログラミングの表現力を持つ新しいプログラミング言語
  • **Erlang仮想マシン(BEAM)**上で動作し、WhatsAppやEricssonなどの大規模システムで実績
  • 高並列・高耐障害性を備えた実行環境
    • 数百万のグリーンスレッドを効率的に管理
    • イミュータブルなデータ構造並列ガベージコレクタによる高速処理
  • 例:多数のスレッドを簡単に生成・管理できるGleamコード
    • list.range(0, 200_000) |> list.each(spawn_greeter)
    • 各スレッドが独立してメッセージを出力

開発体験とエコシステム

  • コンパイラ・ビルドツール・フォーマッタ・エディタ統合・パッケージマネージャを標準搭載
  • 新規プロジェクト作成はgleam newコマンド一発
  • BEAMエコシステムの資産活用
    • Gleam, Erlang, Elixir製の数千のパッケージを利用可能
    • 例:gleam add gleam_jsonでJSONライブラリを即導入
  • テスト・ビルド・依存管理もコマンドで簡単操作

安全性とメンテナンス性

  • null値・例外を排除し、明確なエラーメッセージを提供
  • 実用的な型システムによる堅牢なコードベース
  • コード例:フィールド名のタイプミス時に候補を提案
    • Did you mean 'name'?のような親切なメッセージ

マルチリンガルと相互運用性

  • BEAM上の他言語(Erlang、Elixir)のコードを直接利用可能
  • JavaScriptへのコンパイルにも対応し、TypeScript型定義も自動生成
    • フロントエンドや他のJavaScript環境でも活用可能
  • 例:外部関数やDOM操作のコード例をサポート

コミュニティと多様性

  • 全ての人が歓迎される、フレンドリーで多様性を尊重するコミュニティ
    • 性別・経験・背景不問で参加可能
    • コード・オブ・コンダクトを明示し、安心して参加できる環境を構築
  • Black lives matterTrans rights are human rightsなど、多様性への明確な支持

まとめ・次のステップ

  • 公式ドキュメントの言語ツアーでGleamの詳細を学習可能
  • ニュースレターで最新情報を入手
  • プライバシー保護安心の運営体制

Hackerたちの意見

Gleamのアイデアはすごく好きなんだけど、2026年にあらゆる型のシリアライズを手動で実装したくないな。
この言語の最大の問題だね。でも、gleam/glanceでコード生成を実装するのはかなり簡単だよ。今のところ、良いライブラリがこれをうまくサポートしてない(例えば、分岐型のサポートとか)。[0] https://hexdocs.pm/glance/glance.html
Gleamのコードでは、あまりすべての型をシリアライズしないんだ。ざっくり計算したら、5%未満だね。
Dartにも同じような問題があるよ(そうそう、コード生成ライブラリを使えるけど、やっぱり同じじゃない)。
確かに。GleamはElixirとRustのミックスみたいなもので、どちらのシリアライズも明示的に実装する必要がないんだ。これは彼らが解決すべき課題だね。
数年前にAlpacaで遊んだことがあるけど、楽しかったな。ただ、生成されたコードが普通のErlangで書いたものよりもエラーが少ないとは思わなかった。見た目はイマイチだけど、Erlangのパターンマッチングを使った準ランタイム型付けは結構役立つし、「クラッシュさせろ」っていうErlangの哲学にも合ってると思う。正直言うと、これを言うとちょっと反発があるかもしれないけど、分散アプリケーションでは型システムの有用性が薄れてくる気がする。結局、送信されるのはビットだけだからね。ワイヤーはモナドや整数、文字列、ファンクタなんて気にしない。ただの1と0だし、型システムを強制することが逆に邪魔になることが多いと思う。ワイヤーを通るものには変なことや不確実性がたくさんあって、きれいな型ではそれを捉えきれないことが多い。まだGleamは試してないけど、やってみるつもりだし、これで考えが変わる可能性もあるから、受け入れる準備はできてるよ。
このコメントがよくわからないな。確かにワイヤーを通るのはビットだけど、両端点はそのデータをどう解釈するかを知っておく必要があるよね?型はそのための素晴らしいツールだよ。データとプロトコルのバージョンの検証にも使えるし、ワイヤープロトコルを正確に決めることもできる。だから、型が邪魔になるとは思えないんだけど、分散通信プロトコルを形作るための究極のツールだと思う。
面白いね!全然その意見には賛成できないけど、だってローカルで動いてるものも結局はビットだよね?CPUもモナドや整数、文字列、ファンクタなんて気にしないし。だけど、最終的には高レベルのコードはデータが何らかの不変条件に従うことを期待してる。個人的には、すべてを既知の型にパースしてから、そこから言語のネイティブなデータ構造で扱うのが正しいアプローチだと思う。
あなたは型システムについて根本的な誤解をしているようだね。ほとんどの(最高の?)型システムは消去される。つまり、コンパイル時にしか意味がなくて、コードが健全でできれば未定義動作がないことを保証するんだ。「ただのビット」っていうのは型の世界では意味がない。結局、機械語は人間が(実際には)書いたり読んだりしないものだから。
> 正直言って、これでちょっと反発を受けるかもしれないけど、それは全然構わない。分散アプリケーションでは型システムの有用性が薄れてくると思うんだ。結局、送信されるものはビットに過ぎないからね。実際、Gleamも似たような考えを持っていて、型安全な分散メッセージパッシングができるなんて思わせないし、何十年も続いているこの問題を解決しようとする罠にもはまってない。Gleamの分散コンピューティングでは、外部からのレスポンスを扱うのと同じように動的メッセージを処理することになる。ちょっとボイラープレートが増えるけど、型安全を装うか存在しないかの他の2つの選択肢よりはマシだと思う。
Elixirから来たんだけど、休暇中にGleamを数日試してみたよ。追求しないことにした理由は以下の通り:- アドホック多態性がない(関数のオーバーロードを除いて、たしか)から、物事の動作を定義する標準的な方法がない。まだ多くの慣習が整ってないから、自分のライブラリが例えばJSONのデシリアライズをサポートしているかどうかわからない - マクロがないから、JSONの(デ)シリアライズのような基本的な機能も自分で実装しなきゃいけない - 標準ライブラリや人気のあるライブラリの構造体でも - ファイルシステムにアクセスする方法を調べたら、標準ライブラリはAPIがJSとErlangのターゲット間で共有できないから、fsアクセスを提供してないことがわかった。一番人気のあるErlangターゲット用のfsパッケージも全然質が高くなさそうだった。こんな基本的で重要なことなのに。 - これで、ElixirはBEAM(「Erlang」)上で動くだけでなく、Erlangとのシームレスな相互運用があるのに対し、Gleamは最初からErlang / Elixirエコシステムのほとんどにアクセスできないことに気づいた。代数データ型やResult、Option型、パターンマッチングとデストラクチャリングなど、好きな点もたくさんあったけど、結局はRustが本当に欲しいんだなって思った。私の道はRustに続いてるのかな。
Elixirを9年やってて、そのうち5年はプロで使ってるけど、アドホックポリモーフィズムなんて誰も気にしないよ。コミュニティは「データ用」以外でプロトコルを使わないし、意味がわからん。どこにでもグローバルシングルトンプロセスがあるし、観察してる実践にがっかりしてるけど、それでも一番楽しい言語だね。
> Gleamは、最初からほとんどのErlang / Elixirエコシステムにアクセスできない。Gleamは、BEAM上のすべての言語が相互運用できるから、最初からエコシステム全体にアクセスできるよ。例えば、gleam_otpの静的スーパーバイザーのモジュール内の関数はこんな感じ:@external(erlang, "supervisor", "start_link") fn erlang_start_link( module: Atom, args: #(ErlangStartFlags, List(ErlangChildSpec)), ) -> Result(Pid, Dynamic) もう一つの例として、Elixirパッケージblake2へのバインディングを実装しているパッケージ[0]をランダムに選んでみた。@external(erlang, "Elixir.Blake2", "hash2b") pub fn hash2b(message m: BitArray, output_size output_size: Int) -> BitArray @external(erlang, "Elixir.Blake2", "hash2b") pub fn hash2b_secret( message m: BitArray, output_size output_size: Int, secret_key secret_key: BitArray, ) -> BitArray Gleamに合わないならそれでもいいけど、BEAMエコシステムに頼れないってのは間違いだよ! [0]: https://github.com/sisou/nimiq_gleam/blob/main/gblake2/src/g... [1]: https://hex.pm/packages/blake2
アドホック多態性についてはちょっと悩んでる。確かに面白いことができるけど、他の人が指摘しているように、型安全性は減っちゃうよね。 https://cs-syd.eu/posts/2023-08-25-ad-hoc-polymorphism-erode...
俺は、ONE: JSかBEAMのどっちかに絞ってほしいな。プロジェクトが同時にいろんなことできるって言うと、結局どれも中途半端になることが多いし、混乱するしね。Gleamって、BEAMのElixirやErlangみたいに分散コンピューティングに向いてるのかな?もしJSにコンパイルしたら、その答えは変わる?
GleamはErlangと同じくらい分散コンピューティングに適してるよ。Erlangにコンパイルされるから、Erlangができることは何でもできる。ErlangやElixirのライブラリを使ったり、GleamではやりにくいことをするためにFFIコードを書くこともできる。体験は違うけど、静的型付けの保証を受け入れたいなら、APIはgleam_otpみたいに見えるよ。JSにコンパイルしたら、保証はJSのものに変わるし。個人的には、JSターゲットは大きなプラスだと思ってるし、Gleamを損なうことはないよ。両方がGleamで書かれたフルスタックアプリを作って、共通のコードを共有するのがすごく楽しかった。最も目立つ影響は、標準ライブラリや言語自体にターゲット特有の関数がないこと。Erlang関連のものはgleam_erlangやgleam_otpにあって、ファイルシステムアクセスはパッケージとして提供されてる。Erlangだけに興味があるなら、JSターゲットに触れる必要は全くないよ。
大学でおもちゃプロジェクトにGleamを使ったことがあるけど、主な問題はInt型がErlangとJSで異なる概念にマッピングされることだね。Erlangでは任意精度のIntだけど、JSでは64ビットの浮動小数点数(確か)になる。あと、再帰はJSではすぐに限界に達しちゃうこともある。俺のコードは、JSとErlangの両方で動くことはほとんどなかったけど、スキルの問題かもしれない。
私の「Gleam入門」は、ブログ用のLustreフォームだったんだ。そこでフィードバックを送れるようにした。だから、Gleamでクライアントモジュールをきれいに分けて作成し、それをJavaScriptにコンパイルして静的なブログページに挿入できた。サーバー部分はErlangをターゲットにした別のGleamモジュールだった。モデルやいくつかの定数は「共有」モジュールで共有されていて、チュートリアルと同じような感じ。こういう明示的な分離はすごくパワフルだと思う。サーバー専用のものがクライアントバンドルに入っちゃうかもっていう不安も減るしね。
Gleamに夢中だよ!若いコンピュータサイエンスの学生として、Gleamがプログラミングの楽しさを思い出させてくれたんだ。燃え尽きそうな時にね。実は、関数型プログラミング言語にはあまり興味がなかったんだけど、ElixirやErlangみたいな他のBEAM言語も試したけど、Gleamが一番楽しかった :)
F#は試したことある?FPの議論では結構評価されてるよ。
Gleanは言語オタクから見ると面白いけど、仕事でErlangを使う理由はなかったし、これからも多分ないと思う。大体の人もそうだと思うよ。
文句を言えない技術を避けるのって面白いよね。プロダクションでElixirプロジェクトを見ると、「なんでもっと使わないんだろう」っていつも思う。ここではElixirについて話してるけど。Elixirでは、シンプルな分散ジョブスケジューラーを見たことがあるけど、コードは超シンプルで、約8年間メンテナンスなしで問題なく動いてた。知ってる人は会社を辞めたり、会社の一部を移動したりして、みんな忘れたように振る舞ってた。もう一つの例は、中規模の(機能やコードの観点から)ウェブアプリで、今は30人未満でメンテナンスしてて、他の会社で800人以上に提供してる。ストレスも問題もなく、BEAMのおかげで素晴らしいDXが実現してる(他の会社はJVMベースのナノサービスで溺れてる)。
かなり進んだ例として、ATプロトコルアプリケーションを作るための開発ツールキット「Quickslice」を見ることをおすすめするよ。 https://tangled.org/slices.network/quickslice
リンクを開いて「gleam.toml」がない理由が気になる人へ:このプロジェクトには2つのGleamサブプロジェクトが含まれているよ。server/ディレクトリはBEAMサーバー(フレームワークなし)で、client/ディレクトリはGleamでコンパイルされたJSクライアント(Lustreフレームワーク)だ。残念ながら、サーバー用のテストはたくさんあるけど、クライアント用のテストはないんだ。
今Gleamを試してるんだけど、最近Goを書いてたからか、すごく気に入ってる点がいくつかあるんだ。 - nilがない代わりにOptionとResultがある - ADT(代数的データ型) - パターンマッチングとデストラクチャリング - デフォルトで全てがイミュータブル - `use`の構文糖(最初は変な感じだけど、慣れると結構エレガント) - LSPサーバーが若い言語にしてはすごく良く動く でも一番感じるのは、言語全体のシンプルさが際立ってるってことかな。今のところ、アドホックなポリモーフィズムやマクロがないのはプラスだと思う。これで「魔法のような」コードや、間接的なコードを書く衝動が減るしね。過去には抽象化しすぎてたこともあったけど、今はできるだけシンプルに保とうとしてる。大きなプロジェクトでGleamを試してないから、プロジェクトの複雑さが増すと抽象化が恋しくなるかもしれないけど。Gleamは、LLMの助けを借りて書く小〜中規模プロジェクトにはすごく良い言語になると思う(Vibecodedじゃなくてね)。小さな言語で強い型付けとイミュータビリティがあれば、LLM生成コードに対する良いガードレールになるし、全体の構造を頭に入れたままシンプルで直接的なスタイルのプログラミングを促進すると思う。LLMを自由に動かして、何を書いたか理解してないのが一番問題になると思う。
`<-`の構文は、継続渡しスタイルをプログラマーに優しい形で実現してるって気づくと、さらにクレイジーだよね。
Gleamのパフォーマンスを評価した人がいるかすごく気になる。言語自体はシンプルで理解しやすいし、例えばGoみたいに簡単なんだけど、本当にGoと同じくらいパフォーマンスが良いのか、VMの上で動くから何かコストがあるのか知りたい。
Gleamのランタイムパフォーマンスをざっくり把握するには、ErlangやElixirのベンチマークを見るといいよ。一般的にはPythonより速いけど、そんなに差はない。だからこそ、GleamにはJS / BEAMの代わりにLLVMかGolangのバックエンドがあればいいのにと思ってる。人気のある言語のウェブサーバーベンチマークがここにあるよ: https://stressgrid.com/blog/webserver_benchmark/ BEAMには最近JITコンパイラがランタイムに組み込まれたみたいだから(その投稿の後だったと思う)、今は少しパフォーマンスが良くなってるかも。
自分も似たような言語を作ってるよ。Gleamについての事実は以下の通り。 1. BEAM上で動くから、Goに比べて異常に遅いけど、デフォルトで無限にスケーラブル。実際には、あまり問題にならないことが多い。 2. 遅さは問題じゃないって主張する人もいるけど、I/O待ちに97%の時間を使うなら、10倍遅くても典型的なアプリケーションでは30%くらいで済むってこと。BEAM上でマシンを増やすのは、単一のマシンをスケールさせるより簡単だから、これは本当だけど、Goのコア市場ではあまり関係ない。まるでGoは賢い人たちによって作られたかのようだ。 3. コンポーネントを異なるマシンに移動させると、予測可能性を保証するのがずっと難しくなる。正確で予測可能な分散コンピューティングは、正確で予測可能な並行プログラミングを簡単に見せる。 4. BEAMは共有メモリを許可しないけど、Goは(安全でない形で)許可してる。この違いのパフォーマンスへの影響は大きい場合が多い(だからGoは最終的に安全性を許可した)。Gleamはこれをうまく機能させると主張してるけど、同じ分野で働いている身としては、ヨーロッパに船で行くのと飛行機で行く違いを抽象化しようとしているように感じる。GleamはBEAM向けのものを作るならいいかもしれない(アクターモデルにぴったりな大規模スケーラブルな単一アプリ、通常はチャットやテレコム)。でも、Elixirの代わりに使う理由は疑問だな。Goの構文はちょっと微妙だけど、やってることが本当に素晴らしいから、単に構文が良くて「無限にスケーラブル」だからってGoに勝てるわけじゃない。実際、Goはほとんどの人にとって十分にスケーラブルだよ。もしそうじゃないなら、おめでとう、君は100億ドル以上の会社だね。ホットパスを再設計したり最適化する余裕がある。
過去にElixirでかなりの時間を費やして、そこそこ楽しかったけど、いくつかの欠点もあった。Gleamでのプログラミングは、型安全性以外に日常的にどれくらい違うのかな?