Eは、1997 年に Electric Communities でMark S. Miller [ 1 ]、Dan Bornstein、Douglas Crockford [ 2 ]、Chip Morningstar [ 3 ]らが作成した、安全な分散コンピューティングのためのオブジェクト指向プログラミング言語です。Eは主に並行言語Jouleと、安全な分散プログラミングのための Java の拡張機能である Original-E から派生しています。E はメッセージベースの計算とJavaのような構文を組み合わせています。イベント ループとPromiseに基づく並行性モデルにより、デッドロックが発生しないことが保証されます。 [ 4 ]
E 言語は、コンピュータのセキュリティとセキュア コンピューティングのために設計されています。これは主に、オブジェクト指向コンピューティング モデルに厳密に準拠することによって実現されます。オブジェクト指向コンピューティング モデルは、純粋な形でセキュア コンピューティングをサポートする特性を備えています。E 言語とその標準ライブラリは、プログラマがセキュアなソフトウェアを構築し、ソフトウェア コンポーネントが互いに完全に信頼していなくても連携できるようにするために、機能ベースの設計思想を全体にわたって採用しています。E では、オブジェクト参照が機能として機能するため、機能は計算コストや概念的なオーバーヘッド コストを追加しません。言語構文は、セキュリティ上の欠陥を監査しやすいように設計されています。たとえば、レキシカルスコープにより、特定の変数への影響を調べる必要があるコードの量が制限されます。別の例として、この言語では比較に演算子、代入に演算子を使用します。混乱を避けるために、演算子はありません。==:==
Eでは、すべての値はオブジェクトであり、計算はオブジェクトにメッセージを送信することによって実行されます。各オブジェクトは、vat (プロセスに相当)に属します。各vatには、単一の実行スレッド、スタックフレーム、およびイベントキューがあります。分散プログラミングは、リモートオブジェクト(他のvat内のオブジェクト)にメッセージを送信するだけです。リモートパーティとのすべての通信は、 Eランタイムによって暗号化されます。到着したメッセージはvatのイベントキューに配置され、vatのイベントループは、到着順に受信メッセージを1つずつ処理します。
Eにはメッセージを送信する方法が2つあります。即時呼び出しと結果送信です。即時呼び出しは、非並行言語における一般的な関数呼び出しやメソッド呼び出しと同様です。送信側は受信側が処理を終えて値を返すまで待機します。結果送信では、メッセージを送信しながら、結果のプレースホルダー(プロミスと呼ばれる)を作成します。送信側はプロミスをすぐに処理します。その後、受信側が処理を終えて結果を返すと、プロミスが解決されて結果になります。リモートオブジェクトとの通信では結果送信のみが許可されているため、デッドロックは発生しません。分散システムでは、プロミス機構によってネットワーク遅延による遅延も最小限に抑えられます。
Eの構文はJavaに最もよく似ていますが、 PythonやPascalにもいくらか似ています。変数は動的に型付けされ、字句スコープを持ちます。しかし、JavaやPythonとは異なり、Eはすべて式で構成されています。以下は、非常にシンプルなEプログラムです。
println ( "こんにちは、世界!" )以下は、E 言語で記述された、数値の階乗を計算する再帰関数です。関数はdefキーワードを使用して定義されます。
def factorial ( n : int ) : int { if ( n == 1 ) { return 1 } else if ( n > 0 ) { return n * factorial ( n - 1 ) } else { throw ( "invalid argument to factorial: " + n ) } }最初の行は、関数の引数と戻り値を制約するガード:intです。ガードは型宣言とは少し異なり、省略可能で制約を指定できます。最初のガードは、関数の本体が整数型の引数のみを処理することを保証します。上記の2番目のガードがないと、関数は値を返すことができません。情報が関数から漏れることを事前に確認できることは、セキュリティ監査に役立ちます。:int:int
E言語は安全な協力関係をサポートすることを目的としているため、Eプログラムの典型的な例として、わずか数行のE言語で記述されたシンプルな電子マネーシステムである「ミント」が挙げられます。以下のコードは、各ミントが独自の通貨を持つミントを作成する関数を定義しています。各ミントは、その通貨を保管する財布を作成でき、同じ通貨の財布を2つ持っている人は、財布間で安全に資金を移動できます。ソースコードをざっと調べれば、Eプログラマーは、流通する通貨の量を変更できるのはミントだけであること、通貨は作成することはできても破壊することはできないこと、ミントは独自の通貨しか作成できないこと、そして財布の残高を変更できるのは財布の所有者だけであることを容易に確認できます。
def makeMint ( name ) : any { def [ sealer , unsealer ] := makeBrandPair ( name ) def mint { to makePurse ( var balance : ( int > = 0 ) ) : any { def decr ( amount : ( 0..balance ) ) : void { balance -= amount } def purse { to getBalance () : int { return balance } to sprout ( ) : any { return mint.makePurse ( 0 ) } to getDecr ( ) : any { return sealer.seal ( decr ) } to deposit ( amount : int , src ) : void { unsealer.unseal ( src.getDecr ( ) ) ( amount ) balance + = amount } } return purse } } return mint }E のオブジェクトはキーワードで定義されdef、オブジェクト定義内では、toキーワードが各メソッドの開始点となります。この例のガード式は、値制約 (や のように:(int >= 0)):(0..balance)を指定する方法を示しています。
造幣局の例では、シーラーと呼ばれる組み込みのメカニズムが使用されています。この機能はmakeBrandPair、シーラーとアンシーラーという2つの関連オブジェクトを作成します。シーラーはオブジェクトを箱に封印することができ、アンシーラーは箱の中身を取り出すことができる唯一のオブジェクトです。このお金の例の詳細については、Eのウェブサイトを参照してください。[ 5 ]
貨幣の以下の簡単な例を提示する前に、この例が繰り返し引き起こす混乱を回避しなければなりません。私たちは実際にこの方法で貨幣を運用することを提案しているわけではありません。望ましい貨幣システムは、さらに…