プログラミングスタックをEveはどのように統合するのか

この投稿では、エキサイティングで魅力的な新しいプログラミング言語、Eveについて紹介していきたいと思います。今回は6パートのシリーズのうち、パート1です。

  • 1. プログラミングスタックの全体をEveはどのように統合するのか
  • 2. When logic programming meets CQRS(ロジックプログラミングがCQRSに出会う時)
  • 3. Throwing off our scope chains(スコープチェーンを取り除く)
  • 4. Smalltalk and protein programming(Smalltalk言語とプロテインのプログラミング)
  • 5. The rock-solid foundation for Eve’s big vision(Eveの壮大なるビジョンのための強固な基盤)
  • 6. Why Eve will be perfect for realtime apps(リアルタイムアプリケーションに対してEveが完璧な理由)

Eveは、以前にLight Tableを設立した先見的なチームによる長年にわたる研究開発の成果で、先月バージョン0.2がリリースされました。私がEveを知ったのは、Hacker Newsでそのリリースのことが大きな話題になっていたのがきっかけです。

最新バージョンのEveには、 “Flappy Eve” のような素晴らしいライブデモがあります。

flappy.eveのデモを初見でスクロールしていると、いくつかの魅力的な特徴が目を引きます。

  • IDE(統合開発環境)が、WYSIWYGのブログエディタのような外観です。Eveのコードは、Markdown形式の文章に埋め込まれるように設計されており、極めて文芸的プログラミングと言えます。
  • 構文になじみはないものの、非常に整っており(ある意味スパースであり)アプローチしやすそうに見えます。頭の片隅で、「括弧で囲まれた部分はあるけど、実際のコードはどこなんだ?」と思わずにはいられません。
  • コードは約100行と、とんでもなくコンパクトです。また、todomvc.eveは63行しかありません。ちなみにReactのTodoMVCだと、JavaScriptが300行以上もあります。

以上が私の第一印象です。そして、その後、数時間をかけて、サンプルや関連文書、テックトークを見たりした後の感想が以下になります。

Eveには、「そんなソリューションがあったとは」と思わせてくれるような解決策が山ほどあります。まるで自転車社会で育った人間が、自動車の世界を初めて知り、自転車ベースのアーキテクチャの限界を突然理解したような感じです。

Eveを知ることで、主流のプログラミングのスタックアーキテクチャにおける様々な問題を遡及的に診断することができるようになりました。このシリーズでは、それらの問題の性質やその解決法を説明していきたいと思います。

問題:各層が同じことを別々に行う

ソフトウェアスタックには多くの層がありますが、通常、以下の3つの層が “コアシステム” と呼ばれ、大変な作業を受け持ちます。

  • データベース層
  • リモートAPI層
  • アプリケーション層

しかし、コアシステムとやり取りをする層は他にもたくさんあります。

  • レンダリング層
  • I/Oイベント層
  • コンフィギュレーション層
  • ロギング層

高次のレベルでは、これらの層は全て同じこと、つまりデータの処理を行います。入力値を読み取り、他の値を算出し、内部の状態を変更し、値を出力して他の層に渡す、というようなことです。しかし、それぞれの層に注目してみると、データの処理という基本的な役割の同一性が曖昧になるほどに、無数の違いが見えてくると思います。

異なるデータモデル

1つあるいは複数のオンラインデータベースシステムがあり、それらには、SQLテーブル、Documentコレクション、キー・値マップ/グラフなどのようなデータモデルがあります。

データをJSONやXMLのチャンクとして、あるいはGraphQLのグラフとしてモデル化するようなリモートAPIがあります。

スコープチェーン内で、インメモリデータ構造や変数をモデル化するような実行中のアプリケーションがあります。

異なる操作

データベース層を操作することができるSQLまたはNoSQLクエリには、様々な種類があります。

API層の操作は、HTTP GET経由でデータを照会したり、HTTP POSTなどからデータを更新したりすることで実行できます。GraphQL APIの場合、GQLのクエリや変更で操作します。

アプリケーション層の操作には、スコープチェーンから変数を参照したり、インメモリデータ構造をトラバースまたは変更したりします。


スタックの各層には、それぞれに異なるデータモデルや操作方法があります。

各層の差異が摩擦を生み、エラーの余地を作ります。それぞれの層の特性や役割については個別に判断し、別々のプログラミングパターンを使用しなければなりません。また、たくさんの “グルーコード” を書く必要もあります。

解決策:統一のデータ処理言語

Eveには単一の下層データモデルと単一の操作セットがあり、スタックの全ての層にわたって使うことができます。

統一データモデル

Eveにおいて、データ(または状態)はデータベースのセットの中に存在しています。スタック内のそれぞれの層は別々のデータベースに以下のように対応している場合があります。

  • インメモリのアプリケーションデータは、@sessionデータベースの中に存在します。
  • ブラウザのDOMツリーは、@browserデータベースの中に存在します。
  • ユーザI/Oのイベントは、@eventデータベースの中に存在します。

各データベースにはレコードが含まれています。レコードは他のレコードに対するリファレンスだけでなくプリミティブな値も格納できるキー・値のマッピングです。レコードは括弧で閉じられた単純な構文を保持しています。

データベース内にはレコードを保持するためのテーブルもコレクションもありません。あるのは、リンクされたレコードの構造体を含んでいるデータベースのみです。

Eveのリンクされたレコードのユニバーサルデータモデルは、RDFJSON-LDなどの “セマンティックWeb” のテクノロジに似ています。しかし、Eveの利点は統一データモデルだけではありません。

統一の操作セット

Eveは統一の操作セットでもあります。”search”、”commit”、”bind”の3つの操作がEveの全機能を構成しています。

  • SQLのSELECTに似た、データの “search” クエリ
  • SQLのINSERT/UPDATE/DELETEに似た、データの状態を変化させる”commit”
  • SQLのマテリアライズドビューやMobXの計算値に似た、特別な “推論値” を書き込む “bind” 。bindの素晴らしさについては、このシリーズの後半でさらにたくさんお話します。

Eveの統一データモデルにおいて統一の操作セットを使うことによってスタックの異なる層をコントロールできるのは素晴しいことです。例えば、以下のようにして<div>をDOMにレンダリングします。

DOMツリーが@browserデータベース内に存在しているため、<div>をレンダリングすることはtag: "div"付きのレコードをコードするという意味しか持ちません。


ご覧の通り、スタックの各層には、データモデルと操作セットがひとつしかありません。

全ての層が同じなので、摩擦が減りエラーを起こす余地はさほどありません。特性や役割についてもっと容易く判断できるようになり、それぞれの層に対して似たようなプログラミングのパターンが使えるようになります。全てが既につながっているので、何も “くっつける” 必要はありません。

より高い水準の抽象化

Eveのチームは、アプリケーションスタックの全体にわたって機能する、統一データモデルと統一の操作セットを生み出しました。それを実現するために、私たちの誰もが実現不可能だと思っていた、より高い水準の抽象化を特定しなければなりませんでした。

あなたが既に、今年リリースされたもうひとつの抽象化飛躍である、GraphQLの理解に努めていたなら、この偉業を理解するのに役立つことでしょう。

GraphQLがデータベースでもサーバでも無く、むしろグラフのクエリ言語(または、 “GraphQL” )であるということを理解するには、少々時間がかかります。GraphQLのポイントは、クライアントのAPIビューをRESTエンドポイントの小さな固定セットから
任意のグラフクエリを受け入れる、統一されたリンクデータの構造に変更することです。

GraphQLと同様に、Eveもデータベースのバックエンドやサーバではなく、私たちが使い慣れているものよりも高い水準で抽象化された言語です。Eveの「単純なモデル、データという世界」というタイトルのホームページのあるページから、以下のコードを例にして考えてみましょう。

search @slack blockを実行すると、サードパーティのslackアプリケーションとコミュニケーションを取っていることになり、それは当然内部にデータベースを保持しています。
しかし、GraphQLにおいて任意のAPIの呼び出しが大きなグラフ領域の一部であるように見せかけられるのと同様に、Eveにおいても全てがEveのデータ領域の一部であると見せかけるようになります。

あなたがAPI層に対するGraphQLの動作を気に入り、他の全ての層に対しても一挙に同様の動作をしてくれるものを求めているのであれば、ぜひEveを使ってみてください。