E (programming language)
Encyclopedia
E is an object-oriented programming
language for secure
distributed computing
, created by Mark S. Miller
, Dan Bornstein, and others at Electric Communities in 1997. E is mainly descended from the concurrent language Joule and from Original-E, a set of extensions to Java for secure distributed programming. E combines message-based computation with Java
-like syntax. A concurrency model based on event loops
and promises ensures that deadlock
can never occur.
in mind; this is accomplished chiefly by strict adherence to the object-oriented computing model, which in its pure form has properties that support secure computing. The E language and its standard library employ a capability-based
design philosophy throughout in order to help programmers build secure software and to enable software components to co-operate even if they don't fully trust each other. In E, object references serve as capabilities, hence capabilities add no computational or conceptual overhead costs. The language syntax is designed to be easy for people to audit for security flaws. For example, lexical scoping
limits the amount of code that has to be examined for its effects on a given variable. As another example, the language uses the operator for comparison and the := operator for assignment; to avoid the possibility of confusion, there is no = operator.
Computational model
In E, all values are objects
and computation is performed by sending messages to objects. Each object belongs to a vat (analogous to a process
). Each vat has a single thread of execution, a stack frame, and an event queue. Distributed programming is just a matter of sending messages to remote objects (objects in other vats). All communication with remote parties is encrypted
by the E runtime. Arriving messages are placed into the vat's event queue; the vat's event loop processes the incoming messages one by one in order of arrival.
E has two ways of sending messages: the immediate call and the eventual send. An immediate call is just like a typical function or method call in a non-concurrent language: the sender waits until the receiver finishes and returns a value. An eventual send sends the message while producing a placeholder for the result called a promise. The sender proceeds immediately with the promise. Later, when the receiver finishes and yields a result, the promise resolves to the result. Since only eventual sends are allowed when communicating with remote objects, deadlock
s cannot happen. In distributed systems, the promise mechanism also minimizes delays caused by network latency.
Syntax and examples
E's syntax is most similar to Java
, though it also bears some resemblance to Python
and Pascal
. Variables are dynamically typed and lexically scoped
. Unlike Java or Python, however, E is composed entirely of expressions
. Here is an extremely simple E program:
println("Hello, world!")
Here is a recursive function for computing the factorial of a number, written in E. Functions are defined using the def keyword.
def factorial(n :int) :int {
if (n 0) {
return 1
} else if (n > 0) {
return n * factorial(n-1)
} else {
throw("invalid argument to factorial: "+n)
}
}
In the first line, :int is a guard that constrains the argument and result of the function. A guard is not quite the same thing as a type declaration; guards are optional and can specify constraints. The first :int ensures that the body of the function will only have to handle an integer argument. Without the second :int above, the function would not be able to return a value. Being able to see up front that information escapes out of the function is helpful for security auditing.
Since E is intended to support secure co-operation, the canonical example for E programs is the mint, a simple electronic money system in just a few lines of E. The following code defines a function that makes mints, where each mint has its own currency. Each mint can make purses that hold its currency, and any holder of two purses of the same currency can securely transfer money between the purses. By quick examination of the source code, an E programmer can easily verify that only mints may change the amount of money in circulation, that money can only be created and not destroyed, that mints can only create money of their own currency, and that only the holder of a purse can change its balance.
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
}
Objects in E are defined with the def keyword, and within the object definition, the to keyword begins each method. The guard expressions in this example illustrate how to specify a value constraint (as in :(int >= 0) or :(0..balance)).
The mint example makes use of a built-in mechanism called a sealer. The function makeBrandPair creates two associated objects, a sealer and an unsealer, such that the sealer can seal an object in a box and the unsealer is the only object that can retrieve the contents of the box. See the E website for a more detailed explanation of this money example.
Object-oriented programming
Object-oriented programming is a programming paradigm using "objects" – data structures consisting of data fields and methods together with their interactions – to design applications and computer programs. Programming techniques may include features such as data abstraction,...
language for secure
Computer security
Computer security is a branch of computer technology known as information security as applied to computers and networks. The objective of computer security includes protection of information and property from theft, corruption, or natural disaster, while allowing the information and property to...
distributed computing
Distributed computing
Distributed computing is a field of computer science that studies distributed systems. A distributed system consists of multiple autonomous computers that communicate through a computer network. The computers interact with each other in order to achieve a common goal...
, created by Mark S. Miller
Mark S. Miller
Mark S. Miller is an American computer scientist. He is known for his work as one of the participants in the 1979 hypertext project known as Project Xanadu; for inventing Miller Columns; as the co-creator of the Agoric Paradigm of market-based distributed secure computing; and the open-source...
, Dan Bornstein, and others at Electric Communities in 1997. E is mainly descended from the concurrent language Joule and from Original-E, a set of extensions to Java for secure distributed programming. E combines message-based computation with Java
Java (programming language)
Java is a programming language originally developed by James Gosling at Sun Microsystems and released in 1995 as a core component of Sun Microsystems' Java platform. The language derives much of its syntax from C and C++ but has a simpler object model and fewer low-level facilities...
-like syntax. A concurrency model based on event loops
Event-driven programming
In computer programming, event-driven programming or event-based programming is a programming paradigm in which the flow of the program is determined by events—i.e., sensor outputs or user actions or messages from other programs or threads.Event-driven programming can also be defined as an...
and promises ensures that deadlock
Deadlock
A deadlock is a situation where in two or more competing actions are each waiting for the other to finish, and thus neither ever does. It is often seen in a paradox like the "chicken or the egg"...
can never occur.
Philosophy
The entire language is designed with secure computingComputer security
Computer security is a branch of computer technology known as information security as applied to computers and networks. The objective of computer security includes protection of information and property from theft, corruption, or natural disaster, while allowing the information and property to...
in mind; this is accomplished chiefly by strict adherence to the object-oriented computing model, which in its pure form has properties that support secure computing. The E language and its standard library employ a capability-based
Capability-based security
Capability-based security is a concept in the design of secure computing systems, one of the existing security models. A capability is a communicable, unforgeable token of authority. It refers to a value that references an object along with an associated set of access rights...
design philosophy throughout in order to help programmers build secure software and to enable software components to co-operate even if they don't fully trust each other. In E, object references serve as capabilities, hence capabilities add no computational or conceptual overhead costs. The language syntax is designed to be easy for people to audit for security flaws. For example, lexical scoping
Scope (programming)
In computer programming, scope is an enclosing context where values and expressions are associated. Various programming languages have various types of scopes. The type of scope determines what kind of entities it can contain and how it affects them—or semantics...
limits the amount of code that has to be examined for its effects on a given variable. As another example, the language uses the operator for comparison and the := operator for assignment; to avoid the possibility of confusion, there is no = operator.
Computational model
In E, all values are objects
Object-oriented programming
Object-oriented programming is a programming paradigm using "objects" – data structures consisting of data fields and methods together with their interactions – to design applications and computer programs. Programming techniques may include features such as data abstraction,...
and computation is performed by sending messages to objects. Each object belongs to a vat (analogous to a process
Process (computing)
In computing, a process is an instance of a computer program that is being executed. It contains the program code and its current activity. Depending on the operating system , a process may be made up of multiple threads of execution that execute instructions concurrently.A computer program is a...
). Each vat has a single thread of execution, a stack frame, and an event queue. Distributed programming is just a matter of sending messages to remote objects (objects in other vats). All communication with remote parties is encrypted
Encryption
In cryptography, encryption is the process of transforming information using an algorithm to make it unreadable to anyone except those possessing special knowledge, usually referred to as a key. The result of the process is encrypted information...
by the E runtime. Arriving messages are placed into the vat's event queue; the vat's event loop processes the incoming messages one by one in order of arrival.
E has two ways of sending messages: the immediate call and the eventual send. An immediate call is just like a typical function or method call in a non-concurrent language: the sender waits until the receiver finishes and returns a value. An eventual send sends the message while producing a placeholder for the result called a promise. The sender proceeds immediately with the promise. Later, when the receiver finishes and yields a result, the promise resolves to the result. Since only eventual sends are allowed when communicating with remote objects, deadlock
Deadlock
A deadlock is a situation where in two or more competing actions are each waiting for the other to finish, and thus neither ever does. It is often seen in a paradox like the "chicken or the egg"...
s cannot happen. In distributed systems, the promise mechanism also minimizes delays caused by network latency.
Syntax and examples
E's syntax is most similar to Java
Java (programming language)
Java is a programming language originally developed by James Gosling at Sun Microsystems and released in 1995 as a core component of Sun Microsystems' Java platform. The language derives much of its syntax from C and C++ but has a simpler object model and fewer low-level facilities...
, though it also bears some resemblance to Python
Python (programming language)
Python is a general-purpose, high-level programming language whose design philosophy emphasizes code readability. Python claims to "[combine] remarkable power with very clear syntax", and its standard library is large and comprehensive...
and Pascal
Pascal (programming language)
Pascal is an influential imperative and procedural programming language, designed in 1968/9 and published in 1970 by Niklaus Wirth as a small and efficient language intended to encourage good programming practices using structured programming and data structuring.A derivative known as Object Pascal...
. Variables are dynamically typed and lexically scoped
Scope (programming)
In computer programming, scope is an enclosing context where values and expressions are associated. Various programming languages have various types of scopes. The type of scope determines what kind of entities it can contain and how it affects them—or semantics...
. Unlike Java or Python, however, E is composed entirely of expressions
Expression (programming)
An expression in a programming language is a combination of explicit values, constants, variables, operators, and functions that are interpreted according to the particular rules of precedence and of association for a particular programming language, which computes and then produces another value...
. Here is an extremely simple E program:
println("Hello, world!")
Here is a recursive function for computing the factorial of a number, written in E. Functions are defined using the def keyword.
def factorial(n :int) :int {
if (n 0) {
return 1
} else if (n > 0) {
return n * factorial(n-1)
} else {
throw("invalid argument to factorial: "+n)
}
}
In the first line, :int is a guard that constrains the argument and result of the function. A guard is not quite the same thing as a type declaration; guards are optional and can specify constraints. The first :int ensures that the body of the function will only have to handle an integer argument. Without the second :int above, the function would not be able to return a value. Being able to see up front that information escapes out of the function is helpful for security auditing.
Since E is intended to support secure co-operation, the canonical example for E programs is the mint, a simple electronic money system in just a few lines of E. The following code defines a function that makes mints, where each mint has its own currency. Each mint can make purses that hold its currency, and any holder of two purses of the same currency can securely transfer money between the purses. By quick examination of the source code, an E programmer can easily verify that only mints may change the amount of money in circulation, that money can only be created and not destroyed, that mints can only create money of their own currency, and that only the holder of a purse can change its balance.
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
}
Objects in E are defined with the def keyword, and within the object definition, the to keyword begins each method. The guard expressions in this example illustrate how to specify a value constraint (as in :(int >= 0) or :(0..balance)).
The mint example makes use of a built-in mechanism called a sealer. The function makeBrandPair creates two associated objects, a sealer and an unsealer, such that the sealer can seal an object in a box and the unsealer is the only object that can retrieve the contents of the box. See the E website for a more detailed explanation of this money example.