Oscar Spencer氏は先頃、WebAssemblyにコンパイルされる新しい強く型付けされた高級言語であるGrainのプレゼンテーションをした。Grainには、可変変数の使用が可能な、関数型プログラミング機能 (型推論、パターンマッチング、クロージャなど) がある。Grainには、複合データ構造 (Option、Stack、Result) とシステムコール (I/O、プロセス処理など) の標準ライブラリもある。
WebAssembly Summit 2021での講演で、Spencer氏は、唯一のコンパイルターゲットであるWebAssembly専用に作成されたプログラミング言語であるGrainの主な特徴について説明した。
Grain言語は次のミッションを自ら掲げている:
Grainは、関数型および学術的なプログラミング言語の革新的な機能を最新化し、それらを大衆に提供することを目的としています。多くの言語は素晴らしいアイデアを持っていましたが、最終的には難解であるか、学ぶのが難しすぎるとして却下され、その結果、周りに大規模なコミュニティを結集するのに苦労しました。Grainは、これらのアイデアに新しい命を吹き込み、使いやすく理解しやすい形で提示したいと考えています。
Grainは (OCamlの型チェッカを使用して) 強く型付けされ、その型推論により型注釈の必要性を大幅に削減する。WebAssemblyコアデータ型 (たとえば、i32
が Int32
になる)に加えて、Grainは、ハイレベルの型付き言語で一般的に使用される複合型も提供する。Option
型は、何かが存在する可能性 (Some
バリアントを使用) または存在しない可能性 (None
バリアントを使用) を表す。Result
型は、成功の場合 (OK
バリアントを使用) またはエラーの場合 (Err
バリアントを使用) を表す。Stack
型は、不変のスタックを表す。追加の型と言語構文は、タプル、レコード、配列、リスト、範囲、文字、文字列、セット、マップ、キューなどをサポートしている。
開発者は、汎用データコンストラクタを使用して Enum
データ型を定義できる:
enum Veggie { Squash, Cabbage, Broccoli }
enum Fruit { Apples, Oranges, Bananas }
enum Inventory<produce> { Crate(produce), Truckload(produce) }
let veggieInventory = [Crate(Broccoli), Truckload(Cabbage)]
let fruitInventory = [Crate(Apples), Truckload(Oranges)]
前のコードでは、Inventory
列挙型のデータコンストラクタ Crate
は、produce
型によってパラメータ化されている。
Grainの開発者は Enum
データ型でパターンマッチングが使用できる:
enum Topping { Cheese, Pepperoni, Peppers, Pineapple }
enum Menu { Pizza(Topping), Calzone(Topping) }
let item = Calzone(Peppers)
match (item) {
Calzone(topping) => {
if (checkSpecials(topping)) {
print("These are half off this week.")
} else {
print("No current specials.")
}
},
_ => print("No current specials.")
}
前のコードは、topping
は Menu
型の item
を作成するために使用される Topping
型の値にバインドされている。
パターンマッチングは、レコード、タプル、およびリストでも実行できる:
let list = [1, 2, 3]
match (list) {
[] => print("List contains no elements"),
[_] => print("List contains one element"),
[_, _] => print("List contains two elements"),
[_, _, _] => print("List contains three elements"),
_ => print("List containes more than 3 elements")
}
関数はGrainのファーストクラスの概念だ。つまり、関数は値として使用できる。関数は再帰的に自分自身を呼び出すことができる。JavaScriptと同様に、関数は値の参照をスコープ内に保持することもできる (クロージャ)。
Grainは、開発者が値の文字列表現を定義しなくても値を表示する方法がわかる。Grainはさらに、WebAssembly System Interface (WASI) で定義されたものと一致するシステムコールを提供する。WASIには、非同期I/O、乱数生成、現在時刻へのアクセスなどのAPIが含まれている。
Grainプログラムは、他のGrainモジュールからインポート (または他のGrainモジュールにエクスポート) できるモジュールに分割できる。開発者が外部関数を明示的に提供すれば、Grainモジュールは外部関数をインポートすることもできる。
Spencer氏は、Grainが可能にするハイレベルプログラミングの型を簡単な例で説明した:
将来のGrain開発には、より優れた外部関数インターフェイス、静的リンク、64ビットモードのサポート、DOM標準ライブラリ、マクロなどを含むことが必要だ。
TypeScriptの厳密なバリアントをWebAssemblyにコンパイルするAssemblyScriptも、WebAssembly用に作成されたものとして自己記述し、一般的な複合型 (配列、日付など) を含む標準ライブラリを含んでいる。Grainと同様に、AssemblyScriptはBinaryenを使用してWebAssemblyにコンパイルされる。AssemblyScriptは、コードサイズに気を配りながら、開発者がハイレベル言語で低レベルの制御を行えるように努めている。ただし、AssemblyScriptでは、開発者からより多くの型注釈が要求される場合がある。
TypeScriptと比較すると、各式の型を事前に知っておく必要があるため、AssemblyScriptでの型推論は制限されています。つまり、変数とパラメータの宣言には、型に注釈を付けるか、初期化子を付ける必要があります。
Grainツールチェーン (CLI、コンパイラ、ランタイム、標準ライブラリなど) は、単一のバイナリとして出荷される。バイナリは、MacOS x64、Linux x64、およびWindows x64で使用できる。GrainコンパイラのJavaScriptバージョンは、カスタムバイナリが利用できないプラットフォームで使用できる。
全体の講演はオンラインで入手でき、スライド、コードサンプル、および追加の詳細な説明が含まれている。WebAssembly Summitは、WebAssemblyに関するすべてのことについて毎年開催されるカンファレンスだ。WebAssembly Summitは、2021年4月にオンラインで開催された。