QCon Londonの基調講演でAdrian Colyer氏がプログラミング言語Ponyに言及した。
この5年でデータベースと分散システムが多くの影響を持っているという事実には誰もが親しんでいます。今、私たちはこの世界のフィットするプログラミング言語について面白い仕事をしています。インペリアル・カレッジ・ロンドンで開発されているPonyはとても面白い言語です。
QConでは、幸運にもこの言語の設計者であるSylvan Clebsch氏による公演が行われた。Clebsch氏によれば、Ponyはフィンテックのシステムに自然にフィットする。なぜなら、"...フィンテックではソフトウエアを書かず、パフォーマンスが大事できちんと検証されない時系列のイベントストリーム処理を書く"からだ。これらの処理のほとんどはJavaやC++、Scala、C、OCaml、Erlang、R、 NumPYで書かれている。
Ponyはアクターモデルを使ったネイティブ言語であり、LLVMを使う。アクターモデルはErlangやAkkaで有名であり、1973年のCarl Hewitt氏他の論文から生まれた。アクターは状態管理と非同期メソッドを組み合わせる。フィールドに加え、アクターはひとつのメッセージキューとヒープを持つ。Clebsch氏によれば、Ponyのアクターは独立してガベージコレクションがされ、ErlangやAkkaとは違い、アクターそのものもガベージコレクションされるので、アクターを殺すためのメッセージのようなものは必要ない。手動でのメモリ管理は不要なのだ。
アクターは自分のヒープのガベージコレクションをmark-and-don’t-sweepアルゴリズムを使って他のアクターとは独立して行う。つまり、Ponyは到達可能なグラフに対してはnのオーダーだ。到達不可能なメモリは影響を与えない。アクターのヒープのGCにはsafepointがなく、読み込み、書き込みのバリアも、カードテーブルマーキングもコンパクト化もない。コンパクト化が必要ないので、ポインタのフィクスアップも必要ない。
ひとつのアクターがローカルのヒープをGCするということは到達可能なグラフを走査するということです。他の処理はありません。つまり、アクターが自分のワーキングセットをGCしているときのジッタはかなり少なくて済むのです。GCのときだけでなく、アクターが振る舞いを操作するときも同様です。
Ponyのアクターにはブロッキングをするものがない。安価でオブジェクトとの比較で240バイトのオーバーヘッドが生まれる。ARMのような32ビットアーキテクチャでは156バイトだ。コードを実行していないときはCPUのオーバーヘッドはない。Clebsch氏は次のように言う。“アクターが何もしていないときは、キューの中にもなく、実行環境はアクターについてなにも知りません。”
アクターはメッセージキューを使ってメッセージを渡す。メッセージにはひとつ以上のキューは必要ない。議論されているのが、キューに制限がないということだ。なぜなら"キューに制限がない場合、キューが満杯なら、ブロックするか失敗にするしかありません”、とClebsch氏は言う。ブロッキングによってデットロックが発生する可能性がある。失敗にした場合はメッセージが送信された場合はいつもアプリケーション固有のエラー処理が必要になる。制限付きキューはバックプレッシャーの問題を回避するために使われるが、氏は制限付きキューはバックプレッシャー問題をさらに悪くならないようにする、と言う。この記事の執筆時点ではPonyのランタイムにはバックプレッシャーを提供するための仕組みはない。氏の話によれば、
何も世界が終わるというわけではなりません。特定の領域で利用できるバックプレッシャーを書くのは簡単です。例えば、TCPListenerのバックプレッシャーです。開いているコネクションの数が特定の閾値を超えたら、新しいコネクションの受け入れを中止する、というものです。
次の数ヶ月で、ランタイムに汎用的なバックプレッシャーが導入されます。これは、"満員のキュー"に送信しようとしたアクターの優先度を自動的に下げます。
基本的にはアクターモデルは並列処理を表しており、難しい並列問題に対処するのがPonyの設計の主目的だ。この設計の鍵はデータ競合から自由であり、並列を検知する型システムだ。Clebsch氏によれば、可変性とデータ競合から自由な型システムを持った言語は他にないが、Rustが同じことを型システムとアトミックな参照のカウントを使って実現している。
また、Ponyにはnullがない。かたシステムは代数学のデータ型の上に構築されているので、その意味では、関数型言語と考えることもできる。下の例は、とても簡単なオーダー管理システムでオーダー作成しているコードだ。
ReadSeq[OrderObserver] isoはこの型システムのもっとも重要で素晴らしいコンセプトのひとつを示している。Iso (Isolated)は否定プロパティ上に構築された保証を提供するリファレンスケイパビリティだ。型システムが競合から自由なのはこのようなリファレンスケイパビリティ(rcaps)のおかげだ。
“許可できるのではなく、その存在自体で、プログラム内の他の場所には静的に存在できないということを示しています。Isoはオブジェクトからの読み取りとオブジェクトへの書き込みができる、ローカルなエイリアスもグローバルのエイリアスも拒否します。これはとても強力な拒否の仕組みです。この変更可能なシーケンスについて知ることができるのはアドレスだけです。読み取りも書き込みもできません。つまり、安全に新しいアクターへ送信でき、ロックのような仕組みがなしで可変性を維持します。”
また、Rcapsは型アノテーションであり、分離レベルと不変性を示す。
x: Foo iso // 分離されたFoo
x: Foo val // ブローバルで不変なFoo
x: Foo ref // 可変なFoo
x: Foo box // ローカルで不変なFoo (C++のconstのような)
x: Foo tag // 透過的でないFoo
rcapsを使ったデータ競合の回避が型チェックのときコンパイラによって処理されているということは重要だ。つまり、コードベースの成長によるコンパイラがしなければならない仕事量の増加は線形ではないということだ。Adrian Colyer氏はブログMorning Paperのこの論文についての素晴らしい要約の中でこの点についても言及している。
Rcapsは分離(iso)、不変(val)、不透過(tag)のオブジェクトの参照を他のアクターに渡せるようにする。これによって、メッセージ内の早すぎるオブジェクトのコレクション(参照を持っているアクターがない、または他のアクターから到達できない)を避けるためのコードが必要になる。Ponyはこのためのメッセージプロトコルを使ってる。これについてもColyer氏が説明している。このアプローチは合意プロトコルに似ており、Colyer氏はChandy-Lamport分散スナップショットアルゴリズムと平行して紹介している。Ponyの論文である"Ownership and Reference Counting Based Garbage Collection in the Actor World" – Clebsch et al. 2015,によれば、
アクターが自分のものではない参照を送信したり、受け取ったり、ドロップしたりするとき、その参照の所有者に特定のプロトコルに従ったメッセージを送ります。このメッセージによって所有者は(ローカルの)参照のカウントを更新します。
Ponyはまだ初期段階でリフレクションやホットコードローディングなどの重要な課題が解決されていない。最近の調査では、大多数のユーザがただこの言語をチェックしているだけだが、さらに先へ進もうとしている者もいる。例えば、ニューヨークの会社であるSendenceはフィンテックの製品を近くリリースするつもりだ。
Ponyはオープンソース言語でありコントリビューションを歓迎している。サンドボックスで試すこともできる。
Rate this Article
- Editor Review
- Chief Editor Action