HN 日本語サマリー

← 一覧へ戻る
プログラミング

Rhombus による柔軟なメタプログラミング

Flexible metaprogramming with Rhombus (lwn.net)

102 pointsby spdegabrielle2 コメント

要約

Rhombus は、Lisp 系言語の強力なメタプログラミング機能と Python 風のシンプルな構文を組み合わせた新しいプログラミング言語です。学術的な背景を持ちつつ、実用的な利用を目指しており、Racket のランタイム上で動作し、豊富なライブラリや最適化コンパイラを利用できます。特に、コードをデータとして扱う構文オブジェクトや、言語の拡張性を高めるマクロ機能が特徴です。

全文翻訳

LWN.net へようこそ このサブスクリプション限定コンテンツは、LWN の購読者によって提供されました。何千人もの購読者が、Linux およびフリーソフトウェアコミュニティからの最高のニュースのために LWN に依存しています。この記事を楽しんでいただけたなら、購読を検討してください。LWN.net をご覧いただきありがとうございます! Daroc Alden 2026年6月30日 Lisp 系言語は歴史的にメタプログラミングと柔軟性の分野で世界をリードしてきました。多くの現代言語がマクロのアイデアを採用していますが、Racket のような Lisp 系言語は、マクロを日常的なプログラムに組み込むことを可能な限り容易にしようと、さらに進化を続けています。一方で、Lisp の最小限の括弧ベースの構文は適応が難しく、Lisp はしばしば「Lots of Irritating Silly Parentheses」(たくさんのイライラするようなくだらない括弧)の略だと言われるほどです。Rhombus は、両方の長所を併せ持つ新しいプログラミング言語であり、Racket のメタプログラミング能力と、Python に似たシンプルな構文、そして合理的な標準ライブラリのデフォルトを組み合わせています。プロジェクト この言語は、より広範な Racket プロジェクトの一部であり、「学術界に根ざしています」。Rhombus の 43 人の貢献者のうち、最も活発な 2 人は、それぞれユタ大学のマシュー・フラット氏と香港中文大学のウィング・ヘイ・チャン氏です。Rhombus は両大学で教育ツールとして使用されています。ユタ大学では、チャン氏は Rhombus に独立して貢献しており、実際には香港中文大学のコンピューターサイエンス学部で働いているわけではありません。それにもかかわらず、この言語は単なる学術的な演習以上のものとなることを目指しています。開発は Racket Programming Language Foundation によって支援されており、Racket と Rhombus を実際のプロフェッショナルな用途に適したものにすることを目指しています。この言語は 6 月 22 日に 1.0 リリースを祝ったばかりですが、学術的でない用途の中でも、Economancy カードゲーム用のツールのセットが部分的に書かれています。Rhombus のコアは MIT または Apache 2.0 ライセンスで利用可能ですが、Racket ランタイムの上に構築されており、一部の動的ライブラリには LGPL 3.0 コードが含まれています。Racket のインフラストラクチャの多くを再利用しているため、すでに多数の利用可能なライブラリと最適化コンパイラを備えています。Rhombus プログラムは、インタープリタで実行したり、バイトコードにコンパイルしたり、ネイティブマシンコードにコンパイルしたりできます。Rhombus が Racket と異なる点の一つは、構文以外では、デフォルトのデータ構造の選択です。Lisp 系言語は、コアデータ型として単方向連結リストをよく使用しますが、これは効率の問題を伴います。Rhombus は、多くの操作にログ時間かかる不変ツリー構造を基盤とするリストを使用します。フラットでミュータブルな配列、ツリーベースのマップとセット、ハッシュベースのマップとセットも標準ライブラリで利用可能です。構文 Rhombus の構文は Python にかなり似ており、インデントベースで、インデントされたブロックの開始を示すために「:」を使用します。わずかな違いは、if 式や同様のコンテキストでブランチを区切るために「|」記号を使用することです。最も明確な説明はおそらく例でしょう(階乗関数の実装):fun factorial(n): if n <= 1 | 1 | n * factorial(n - 1) より命令型のプログラマーは、for ループを使用した以下のバージョンを好むかもしれません。一般的な排他的範囲 1..n ではなく、包括的範囲 1..=n の使用に注意してください。fun factorial(n): def mutable p = 1 for (i in 1..=n): p := p*i p デフォルトでは、変数はイミュータブルなので、ループが p の値を変更できるようにするには、ミュータブルバインディング演算子が必要です。しかし、例はより短くすることができます。Rhombus の for ループは、Lisp 系言語以外では珍しい機能をサポートしています。それは、ループの結果を最終的な値に結合するために使用されるオプションの「リデューサー」です。math.product リデューサーは、ループから返されたすべての値を乗算し、次のように記述できます。fun factorial(n): for math.product (i in 1..=n): i この機能により、他の言語で見られるリスト内包表記に相当するものが、単なる for ループとなり、List リデューサーを使用して結果をリストに収集します。for ループは、all または any リデューサーを使用して、マップ、セット、またはブール値を生成することもできます。典型的なプログラミング言語では、このような組み込み構文は標準ライブラリによって提供される型に対して機能することが期待されるかもしれませんが、ユーザー定義型に対しては機能しないでしょう。しかし、Rhombus のマクロは、新しいリデューサーの作成を含む、言語のほぼすべての部分を拡張するために使用できます。ほとんどのプログラムではそれを行う必要はないかもしれませんが、プログラムを単純化できる場合にはオプションとして持つことは良いことです。マクロ Rhombus のマクロは、単一引用符を使用して Rhombus コードの断片を表す構文オブジェクトを生成し、「$」を使用してプレースホルダーを示します。従来の Lisp 系言語がリストでコードを表すのとは異なり、Rhombus の構文オブジェクトは独自のデータ型です。これにより、行番号や位置などの追加のメタデータを保持でき、Rhombus はマクロを正しく考慮したスタックトレースのような役立つエラーメッセージを生成できます。構文オブジェクトは、名前の解決方法を制御するメタデータも保持しており、プログラマーはマクロが環境から名前をキャプチャするタイミングと方法を制御できます。ハイジーンマクロと非ハイジーンマクロの両方を記述できますが、ハイジーンマクロがデフォルトです。小さなマクロの例として、組み込みの when マクロの観点から Ruby の後置 if を実装するために必要なコードはすべて次のとおりです。import: rhombus/meta open // マクロ expr を定義するために必要です。macro '$action if $test': 'when $test | $action' println("Hi!") if (foo == bar) ある意味で、この種の構文オブジェクトは TemplateHaskell が使用する方法を連想させます。しかし、TemplateHaskell とは異なり、Rhombus マクロは通常の関数が定義できる場所ならどこでも定義でき、使用される文脈に応答します。上記の例は、式が期待される場所ならどこでも使用できるマクロです。リデューサーマクロは reducer.macro で定義され、インポート、パターンマッチなどの処理をカスタマイズするマクロにも同様の構造があります。マクロが操作できる文脈のリストは固定されていると予想するかもしれません。Rhombus ではそうではなく、文脈を操作するための関数をユーザーに公開しています。プログラムが Rhombus の基本的なインデントベースの構文を使用している限り、プログラマーは必要に応じて独自の文法や式の種類を自由に定義できます。その他の拡張形式 そのような柔軟性のもう一つの例は、Rhombus の型チェックへのアプローチです。Rhombus は、ある意味では静的型付け言語ではありません。しかし、型注釈を追加すると、そのように見えることがあります。fun factorial(n :: Int) :: Int: def mutable p :: Int = 1 for (i in 1..=n): p := p*i p // factorial("foo") を呼び出すとエラーメッセージが表示されます:// factorial: 引数が注釈を満たしていません // 引数: "foo" // 注釈: Int Rhombus は、プログラマーが式に任意の静的情報をアタッチし、その静的情報がどのように推論、拡張、チェックされ、マシンコード生成に使用されるかのルールを定義できるようにします。デフォルトでは、言語は注釈を段階的型システムの一部として扱い、可能な限り型を推論し、それを使用してエラーメッセージを提供し、より良いマシンコードを生成します。しかし、プログラマーが独自のクラスの静的情報を Rhombus プログラムにアタッチすることを妨げるものはありません。例えば、プログラム全体での機密データのフローを追跡するため、または関数の漸近実行時間を追跡するための注釈システムを定義することが可能です。マクロはこの静的情報にアクセスして、推論された値に応じて式を異なる方法でコンパイルできます。Rhombus が言語のすべての実装詳細を言語自体内で公開する傾向は、言語指向プログラミングへのプロジェクトのコミットメントの一部です。