A Better Mousetrap (Distributed Objects)

Despite being jaded and feeling that you've seen it all before, its important to keep your sense of wonder at the possibility of seeing something new. There are new ideas in software. Maybe the last cool idea that captured your imagination didn't turn out to be as amazing as you had hoped. Don't give up. The next idea might be better. It probably means that the first idea didn't solve the whole problem, or had some flawed assumption. But now you know more about the problem and can try again.

Simplicity is the result of lots of hard work.

This is how I feel about my work on distributed objects. First of all, let me say that CORBA, RMI, and DCOM are pretty much complete failures. Ok, Ok. I know that some big systems have been built with CORBA. How could these fancy technologies have been stomped by something as whimpy as Web Services and REST? Have people lost their minds? Is there no answer at all?

I think that both CORBA and Web Services are fundamentally flawed. But that is not the interesting point. The interesting point is that they both have gotten something right. If you combine the good parts of each, and avoid the flaws, then the combination might actually be a good solution. So, what are the problems?

The problem with CORBA/RMI is granularity. Clean object-oriented design encourages fine-grained methods. But these are death to distributed systems. So you have to use Data Transfer Objects and Remote Facades to make things work. Its a mess. Automatic proxies are an invitation to poor performance.

Web Services can use document-oriented approach, which encourage large-granularity designs. But the programming model is terrible. You spend all your time creating documents that describe the actions you want to perform and decoding results. Its the opposite of direct manipulation.

The hidden assumption behind both these approaches is that distribution can be implemented as a library. This is such a deep assumption that we don't even realize its there. We say, if you are going to implement distributed computing, you have to create a library to do it... and so you create proxies, documents, etc... but you haven't realized that you've already lost the game before you started. Its similar to the arguments that threads cannot be expressed as a library. I'll add to that my assertion that regular expressions cannot (effectively) be implemented as a library.

What happens if you drop this assumption? We started with a simple observation. If the problem with CORBA/RMI is granularity, lets look at that. The problem is that one call is one round-trip, and two calls is two round-trips. CORBA/RMI is not compositional from the viewpoint of communication. There is no reason why two calls should take two round-trips. So we invented an a language notation for specifying groups of calls that should be performed together:

batch (r) {
print( r.op(3) );
print( r.get() );

In this example, "r" refers to a remote object. The calls to "op" and "get" are both executed in one round trip to the server. Voila! Compositional remote services. You can also execute programs with complex dependencies among the remote parts:

batch (r) {
Foo x = r.locate(3);
print( x.get() );

In this case the remote method returns a Foo object, which is then used in the next call. But since all of the action happens on the server within a batch, there is no need for the client to ever refer directly to "x". No proxies! What happens is that the program is partitioned into a remote part and a local part. The remote part is a script, which runs on the server and returns a result:

REMOTE: result = r.locate(3).get();

The local part then uses the result for the local computation:

LOCAL: print( result );

The result can be multiple values, and the script can contain loops and conditionals. See the papers for more examples. It turns out that these "remote scripts" are isomorphic to documents in document-oriented web services. Thus our new idea of "batches" combines the best parts of CORBA (objects!) and Web Servies (documents!) into one.

We took us so long to discover it? Simplicity is the result of hard work.

Here are some papers with details:

Generic Syntax: Lisp parsing + C notation

I've been working with Jose Falcon, undergrad here at UT, for almost a year on this crazy idea for an approach to syntax that combines aspects of Lisp S-Expressions and familiar Algol/C/Java notations. The idea is to use a generic syntax, as in Lisp, but extend it to include many of the common syntactic conventions found in programming languages, grammars, and style sheets. Lisp only recognizes these characters: "(.,')" and space. Our language, called Gel, recognizes {}, [], (), and arbitrary unary and infix operators. So you can write
{ a + (x ** 3) ==> x | y.z; x := 37; if: a=3 then: print(3, f[x]); }
and have it parse just as you would expect. We tag keywords with a ":", because they have to be generic too. To get operators to work right, we make spaces meaningful. Thus:
a +b == a(+b)
a+ b == (a+)b
a + b == (a)+(b)
This corresponds to common usage in Java/C and also most grammar notations:
E ::= E | ("+" E)*
also parses correctly in Gel. Its basically a "super-lexer" just as Lisp is. We will get the source code up soon so you can check it out. Here is the paper. The work will be presented at IFIP Working Conference on Domain Specific Languages (DSL WC).