見出し画像

DFINITY|プログラミング言語「Motoko」について

Motoko はまったく新しいプログラミング言語 (つまり、Typescript から Javascript へのトランスパイルはありません) であり、WASMにコンパイルされますが、Javascript を使用したことがある人にとっては、ほとんどの部分で非常になじみのあるものです。


WASM は Web Assembly の略で、言語がサポートしている場合にコンパイル ターゲットとして使用できます。有名な例は、C、C++、Rust です。Motoko はGarbage Collectionを使用し、そのコンパイラは OCaml (はい、さらに別の言語) で記述されています。


Motoko は、WASM をサポートするすべてのプラットフォームで選択する汎用プログラミング言語として使用できます。Motoko はstrong type systemを使用し、complete asynchronyを念頭に置いて作成されました。


そのアーキテクチャは、Actorsの概念を中心に構築されています。聞き覚えがありますか?


おそらくそうではありませんが、本当に素晴らしいラビットホールが必要な場合は、時代をはるかに先取りしたTelescript 言語を検索してみてください。Actorsについて議論することはこのテキストの範囲外ですが、ここに簡単な紹介があります。


Actorsは、OOPのクラスと非常によく似た外観と動作をしますが、他のアクターにメッセージを送信する機能によって強化されています。各Actorsはキューを使用して、受信メッセージの順序付けと処理を自動的に管理します。


ES6+ の Promises と同様に、Motoko はFuturesを使用して各Actorの操作の結果を表します。したがって、Futures を使用すると、メッセージを同時に送信できます。これは、操作が呼び出された後の任意の時点で結果が返される可能性があるためです。


Motoko はDfinity財団によって開発されました。この財団は、Internet Computer と呼ばれる最新のWeb分散型アプリケーションのソリューションを提供します。


このアイデアは、現在の Web スタックを独自仕様 (AWS、GCP など) から離れて、プロトコルで定義されたdecentralized governance(分散型ガバナンス)システムである「open」プラットフォームに移行することです。


そのアーキテクチャにより、複数のコンピュータを 1 つの非常に強力な仮想マシンのように動作させることができます。Motokoを試すには、Dfinity の Canister SDK をインストールする必要があります。プロジェクト全体はまだ非常に若いですが、Web の最先端にとどまりたいだけでも、チェックする価値があります。



DFINITYの研究者兼エンジニア Andreas Rossbergによる解説


シームレスな開発者体験を提供するために、Motoko と呼ばれる特殊なプログラミング言語を作成したいと考えていました。


これは、インターネット コンピューターのプログラミング モデルを直接サポートするように設計されており、アプリケーションを効率的に構築し、このプラットフォームのより珍しい機能の一部を利用することを容易にします。


Dfinity では、分散型クラウド コンピューティングプラットフォームであるInternet Computer を構築しています。これは、開発者がアプリケーションやサービスをインターネット上に直接展開できるシームレスなソフトウェア ユニバースとして考えられています。


このビジョンを実現するために、プラットフォームの実行環境の共通言語としてWebAssemblyを決定しました。これにより、開発者は WebAssembly にコンパイルできる任意の言語でプログラミングできます。


WebAssembly


まず、我々はについて簡単に話をする必要がありWebAssembly -aka Wasm。お気づきかもしれませんが、Wasm は移植性、安全性、効率性を目的とした新しい低レベルのコード形式です。


最初の使用例は Web でしたが、実際には名前が間違っています。W3CワーキンググループでWasmを設計したとき、オープン スタンダードおよびユニバーサルプラットフォームとして慎重に作成しました。


つまり、特定のプログラミング言語、パラダイム、コンピューティング環境、またはプラットフォームを対象とするものではなく、Web にまったく関連付けられていないことを確認しました。したがって、クラウド コンピューティング、エッジ コンピューティング、モバイル、組み込みシステム、IoT、ブロックチェーンなど、他の多くの環境で Wasm が採用されているのは偶然ではありません。


Wasm には非常に多くの設計上の考慮事項があり、その中には明白なものもあれば、かなり微妙なものもありました。ここに入るには多すぎます。Wasm の技術的目標、設計の選択、形式的な意味、および実装技術に関するかなり包括的な議論は、Communications of the ACM で公開された科学記事に記載されています(この記事のより古い、より技術的なバージョンは、ここから自由にアクセスできます)。


他の仮想マシンと比較した Wasm の主な違いは、特定のプログラミング言語用に最適化されておらず、最新の CPU の命令とメモリ モデルに直接対応するバイト コードを使用して、基盤となるハードウェアを単に抽象化していることです。


それに加えて、Wasm は強力なモジュール性と厳格な数学的仕様を通じてサンドボックス化をサポートしており、実行が安全で、未定義の動作がなく、(ほぼ) 完全に決定論的であることを保証します。さらに、これらのプロパティには、実際に機械で検証された数学的証明があります。


全体として、これらの特性は、Dfinity の Internet Computer など、移植性、安全性、一般性、およびパフォーマンスに高い期待が寄せられる幅広い環境とユースケースで Wasm を魅力的な選択肢にすることを目的としていました。


Internet Computerの作成


Internet Computer は、安全なソフトウェアと新しいタイプのオープン インターネット サービスをホストする分散型クラウド コンピューティング プラットフォームです。強力な暗号化コンセンサス プロトコルを使用して、多くの仮想サブネットワーク (シャードと呼ばれることもある) でオーバーレイされた (信頼できない可能性がある) コンピューティング ノードのピア ツー ピア ネットワーク上で計算を安全に複製します。


Wasm の利点は、このプラットフォームで実行されるプログラムを表すための明らかな選択でした。また、開発者を 1 つの専用プラットフォーム言語に限定するのではなく、「すべての言語」に潜在的にオープンにするというアイデアも気に入りました。


それはともかく、その理論です。実際には、既存のプログラミング言語を Wasm に移植するのは簡単なことではありません。明らかに、新しいコンパイラ バックエンドを実装する必要があります。それは楽しいことですが、努力はそれだけではありません。


言語のランタイム システムとライブラリ プリミティブの移植も必要です。また、スレッド、コルーチン、例外、末尾呼び出しなど、現在 Wasm で簡単に実装できない、特に高水準言語に関連する機能がまだいくつかあります。Wasm をそれぞれの機能で強化するためのさまざまな提案が予定されていますが、標準化に向けてまだ最終決定されていません。


Wasm を対象とした実験的な言語の実装はすでに多数ありますが、そのほとんどはまだ全盛期の準備が整っていません。含まれているものには、C/C++ や Rust などの低レベルのシステム言語が含まれます。


これらは確かにそのユースケースには適していますが、メモリ管理を手動で干渉するよりもアクセシビリティ、生産性、および高い保証が望ましいインターネット コンピューター向けの高レベル アプリケーションを開発するための理想的なツールとは言えません。


Internet Computer を含む一部のプラットフォームでは、Wasm を実行するために克服する必要のある追加のハードルがあり、それらは提供するコンピューティング環境の制限に関係しています。たとえば、Dfinity の Internet Computer には、従来のオペレーティング システムとの類似点がほとんどありません。


ファイル、I/O、または言語実装で当然と見なされ、ランタイムやライブラリで自由に使用される他の機能のような機能はありません。つまり、既存の言語の移植は、コードを微調整するだけの問題ではありません。不足しているプラ ットフォーム機能の使用を置き換える、それらを削除する、またはまったく異なる設計の選択を行うための新しい手段を見つける必要がある場合があります。


WASIなどの取り組みは、この問題にある程度対処しようとしていますが、まだ初期段階にあります。これらの要因により、一般的な Wasm ポートがすでに存在する言語を採用する場合でも、Dfinity の Internet Computer への言語ポートの実質的な作業は避けられません。


同時に、インターネット コンピューターの言語は、プラットフォームの主要な概念へのアクセスを提供する必要があります。非同期メッセージ パッシングによる分散プログラミング モデル、サイクル (別名ガス) などのリソースの概念、およびその他のいくつかの特異性です。確かに、それらはすべてライブラリとして利用できるようにすることができますが、適切な構造をネイティブに含む言語は、はるかにシームレスなプログラミング体験を提供できます。


地上に出るためにとにかく仕事をしなければならないのなら、最適なユーザー エクスペリエンスを提供し、インターネット コンピューターのプログラム方法に関する私たちのビジョンを伝えることができるものを作成することに自分自身を適用してみませんか?


Motoko


それが、さらに別の言語を作成するリスクにもかかわらず、Motokoを作成することにした理由です。私たちは、安全で使いやすく、プラットフォームの概念をシームレスに公開する言語と、十分に親しみやすく、ほとんどのプログラマーにとってアクセスしやすい言語を望んでいました。現在、後者の目標は、それが言語のセミコロンと中括弧の陣営にしっかりと収まることを事実上避けられないものにしています。そして、このキャンプには適切な言語は存在しませんでした。


しかし、Motokoのどちらかというと従来型のSkinは表面的なものに過ぎず、その内面は現代の言語のものです。たとえば、すべての構築物は、それがガベージコレクションを持っている、それはバリアント型と静的にチェックパターンマッチングを持っている、それはクロージャを持っている、式であり、もちろん、それは実際に音で柔軟な型システム、すなわちを持っている、それは実際に保証がないことをクラッシュ、未定義の動作、データの解釈の誤り、スイッチのケースの欠落などの特定のエラー。穴なし! 


同時に、私たちは意図的に空想にふけったり、車輪の再発明を試みたりするのではなく、実践的および理論的な豊富な歴史に基づいて構築し、この分野で何十年にもわたって学んだ教訓を認めました。よく理解されている機能の一貫した組み合わせに加えて、Motoko の設計には、フット ガンを最小限に抑え、安全性の面でエラーを最小限に抑えるための多くの小さな決定が組み込まれています。


null はデフォルトでは発生せず、フィールドはデフォルトでプライベートなどです。ああ、継承はなく、サブタイプのみです。


Motoko のこれらの部分を実装し、Wasm にコンパイルするのは、従来のコンパイラ技術です。OCaml で記述された Motoko コンパイラは、型指定された中間表現を使用し、いくつかの変換パスを使用して、Wasm バイト コードを出力します。生成された Wasm モジュールには、C および Rust で記述された小さなランタイム システムが含まれており、主に Wasm メモリをヒープとして使用する単純なガベージ コレクターを実装します。それは難しいことではありませんでしたが、ここには改善の余地がたくさんあるのは確かです。


Actors


ただし、Motoko の中心的な機能は、構文と型システムの両方でアクターを直接サポートしていることです。アクター モデルは 40 年以上前のよく知られた概念ですが、残念なことに、ほとんど主流の言語にはなっていません。アクターは、送信可能なメッセージを処理するための一連のメソッドとともにプライベート状態をカプセル化するという点で、オブジェクトのようなものです (そして、Motoko ではそのように見えます)。


ただし、すべてのメッセージ送信は非同期です。したがって、OO の従来のメソッドとは異なり、アクター メソッドには結果がありません。さらに、すべてのメッセージはアクターによって順次受信されます。つまり、メッセージが同時に送信される場合でも、アクターには暗黙的なメッセージ キューがあり、メソッドはアトミックに実行されます。


アクターは、競合状態 (原子性とカプセル化された状態のおかげで) とデッドロック (実行がブロックされないため) を自動的に防止するため、並行プログラミングの優れたモデルであり、したがって、多くの並行性のバグを除外します。プログラマーがロックを定義する必要はありません。アクターは、分散プログラミングの優れたモデルでもあります。なぜなら、非同期性は、潜在的にリモートの受信者にメッセージを送信することに伴う待ち時間を自然に処理するからです。


そして最後に、アクターは、アプリケーションがいわゆるキャニスターの形で展開される Dfinity の Internet Computer に最適です。—本質的に、サブネットワーク間で通信できるWasm モジュールとして表されるアクター。モジュール エクスポートをアクター メソッドとして直接解釈できるため、Wasm のモジュール コンセプトはこれに最適であることがわかりました。


そのため、Motoko アクターは Wasm モジュールにコンパイルします。そこで、メソッドは、プラットフォームによって定義された特別なパラメーター規則を使用してエクスポートされた Wasm 関数になります。



つまり、Motoko のアプリケーションは (または複数の) アクターであり、Wasm モジュールにコンパイルされた大きな非同期オブジェクトです。Wasm のメモリの概念により、そのようなアクターは最大 4 GiB の内部状態をすぐに管理できますが、それぞれが独自のメモリを持つ複数の Wasm モジュールをリンクすることでさらに拡張できます。私たちは、最初のユーザーがこのメモリ制限にどれだけ早く到達するかを知りたいと思っています。


Futures


非同期プログラミングをより便利に、シーケンシャルでそれを表現できるようにするには、「ダイレクトスタイル、」元子は、プログラミング言語の研究の年代記から別の40 +歳のアイデアを採用している幸いにも最近、もう少し普及するようになった1ただし:先物(とも呼ばれます一部のコミュニティでの約束)。Motoko では、これらは「async 値」、つまり「async」キーワードの前に付けられた式によって生成される「async<T>」型の値の形式で具体化されます。特に、関数本体は async 式にすることができるため、他の言語に存在する「非同期関数」のよりモノリシックな概念を自然に置き換えることができます。



これにより、アクター メソッドは結果を得ることができます - それらが Future である限り。Future はその値を取得するために待つことができますが、他の現代言語で知られている async/await モナドに似た、別の async 式の内部でのみ可能です。



Motoko コンパイラーは、従来の CPS (継続渡しスタイル) 変換を介してこれを実装し、各待機ポイントを、待機の継続を表す個別の Wasm 関数 (およびいくつかのクロージャー環境) に変換します。実際、これは二重の CPS です。これは、すべてのメッセージに、それぞれの失敗継続を伴う失敗応答を含めることができるためです。慣例により、非同期の結果を持つメソッドは、結果の値を引数として持つ応答メッセージを送信するものです。このメッセージは、作成された継続関数によって受信され、キャプチャした実行を再開できます。応答を待っていても、アクターはブロックされません。その間、他のメッセージを自由に受信できます。



Persistence



Motokoにとってもう1つの重要な考慮事項は、開発者がまったく新しいタイプのコンピューティングを学ばなくてもブロックチェーン技術を利用できるようにすることでした。そこで、現在の種類のブロックチェーン プログラミング言語で必要になる可能性のある特別な知識をすべて取り上げました。たとえば、ブロックまたはブロックの高さの観察可能な概念はなく、ブロックチェーンの状態を更新するための明示的な構造も、ファイルやデータベースなどの永続ストレージにデータを書き込むための他の API もありません (ただし、ライブラリとしてエミュレートできます)。 


代わりに、インターネット コンピュータは直交永続性を実装します。—プログラムが「永遠に」実行され、そのメモリが生きている (少なくとも明示的に削除されるまで) という幻想を持つ、もう 1 つの古いアイデアです。Motoko では、これは、開発者が明示的にデータを保存することを心配したり、ファイルや外部データベースを気にしたりする必要がないことを意味します。



プラットフォームは、メソッド呼び出し間でキャニスターのプライベート状態を透過的に保存および復元します。Wasm モジュールの状態はモジュールのメモリ、グローバル、およびテーブルで明確に分離されているため、これは Wasm エンジンへの改造が比較的簡単でした。ほとんどの場合、オペレーティング システムによって公開されている仮想メモリ技術を使用して、Wasm メモリを監視するだけで十分です。このようにして、プラットフォームはそのようなメモリ内のページがいつ変更されたかを認識し、ダーティ ページを永続化するために必要な措置を講じ、分散コンセンサス プロトコルのためにそれらをハッシュすることができます。



Beyond Motoko: Interface definitions



Internet Computer は Wasm を実行しているため、Motoko はアプリケーションを作成するための 1 つのオプションにすぎません。他の言語を選択できるようになることを楽しみにしています。その場合でも、各言語は Wasm で表されるキャニスターに一律にコンパイルされるため、これらのキャニスターは、ソース言語に関係なく、メッセージ送信を通じて互いに自由に通信できます。



このような相互運用性を明確にするために、Motoko から独立したCandidという名前の汎用インターフェース定義言語( IDL )も導入しました。キャニスターが理解する一連のメッセージと、送信されるデータのタイプについて説明します。データは、Motoko 型システムまたは他のプログラミング言語の型システムから独立した標準データ型 (数値、テキスト、配列、レコード、バリアント、関数、他のキャニスターへの参照) の組み合わせによって Candid で記述されます。



ふー、また別の型システム?そうですね、プログラマーはおそらく、Motoko コンパイラーがアクターのエクスポートとインポートのためにそのようなインターフェース記述を自動的に消費および生成し、それらを対応する Motoko タイプとの間でマッピングできることに満足するでしょう。また、各メッセージの引数データをシリアライズおよびデシリアライズするための適切な Wasm コードを自動的に生成し、Candid が指定するバイナリ形式と Motoko の内部表現を透過的に相互変換します。



このようにして、Motoko プログラムは型に富んだ方法で外部キャニスターと通信し、プログラム内のローカル オブジェクトであるかのようにリモート呼び出しを表現できます。これは、リモート キャニスターが Motoko で書かれているか、たとえば Rust で書かれているかどうかに関係なく当てはまります。型情報はキャニスターのインターフェース記述で十分です。単なる利便性に加えて、インターフェイスは強力な形式のモジュール性も提供します。つまり、実装にアクセスしなくても、プログラムを他のアクター/キャニスターに対してタイプチェックできます。


結論


私たちの目標は、インターネット コンピューターが、すべての言語が平等な権利を持ち、キャニスターの境界を越えてシームレスに対話できる多言語プラットフォームになることです。Motoko は多くの選択肢の 1 つにすぎません。これは、インターネット コンピューター プラットフォームをオープンなものにするために重要です。



Wasm はこれまでのところ、この目標を達成するための用途の広いコード形式であることが証明されています。特に、そのシンプルさ、モジュール性、安全で決定論的なセマンティクスの恩恵を受けています。しかし、これらの優れた特性にもかかわらず、異なる Wasm エコシステム間でのアプリケーションは言うまでもなく、コンパイラーとライブラリーの移植は、むき出しのコード以上のものが含まれるため、期待するほど簡単ではありません。しかし、ワズムはまだ若いので、いくつかの障壁が予想されます。



私たちが待ち望んでいる次の Wasm の最大の機能は、ファーストクラスの参照型と関数参照の出現です。これにより、Wasm モジュール (および Motoko プログラム) がインターネット コンピューター プラットフォームと通信するための、よりクリーンなシステム API が作成されます)。興味のプログラマは、SDKの詳細を見つけることができるこことGitHubの経由元子ベースライブラリに貢献こちら。



Andreas Rossberg は、DFINITY の研究者兼エンジニアであり、DFINITY の Internet Computer の新しいプログラミング言語である Motoko の開発を率いています。DFINITY に入社する前は、Google のエンジニアとして Chrome で実行される V8 JavaScript エンジンに取り組んでおり、Max Planck Institute for Software Systems でプログラミング言語の理論、設計、実装の学術研究者としても働いていました。彼は WebAssembly の共同設計者の 1 人であり、その仕様を作成しました。




この記事が気に入ったらサポートをしてみませんか?