The Global Program Grid (GPG) is a new way to make programs interact over the Internet in a strongly-typed and object-oriented manner. It comprises of (1) a subset of URI called Uniform Type Locator (UTL) for locating the definition of a data type, (2) a new HTTP-like protocol named Internet Metaobject Protocol (IMOP), and (3) a new programming language named Meso. GPG is as light weight as RESTful services, but without the need of processing ad-hoc APIs manually. GPG is as strongly-typed as the Web Services, but without the mind-boggling WSDL file. GPG also provides similar OO features as in CORBA, but without cumbersome middleware gets in the way.
|World Wide Web||Global Program Grid|
Architectural-wise, the Global Program Grid is somewhat similar to the World Wide Web. The relationships between UTL, IMOP, and Meso are comparable to those between URL, HTTP, and HTML. The difference is that WWW links documents, whereas GPG links programs. Since hypertexts and interlinked programs are very different beasts, they inevitably need very different protocols and languages. Nonetheless, they both aim to facilitate resource sharing in a world-wide scale such that everyone can freely share their resources, and uses those shared by others.
A UTL looks just like a URL but without the double slashes (//) for brevity. Semantically, UTLs are more specific than URLs in that a UTL must point to a typed programmatic resource, such as an object instance or an abstract interface definition. A UTL specifies how a data type's definition can be located. One may use the mechanism identified by a UTL's type scheme to reflect (i.e., introspect) the type definition from its type authority. A UTL gives a programmatic resource a globally unique name that can be used to locate its definition regardless the context where the UTL is referenced. This is the key concept to understand the Global Program Grid.
Some UTLs do not have a type authority portion. In such case, the type definition is either predefined by the type scheme, or can be obtained in a special way known to the type scheme, albeit the result might not be globally unique. Most data types in current programming languages can be identified by UTLs without type authority. For example, the UTL java:int represents the predefined Java primitive type int, whereas the UTL java:foo.Bar represents the Java class named foo.Bar. The definition of the latter can be located by Java class loaders, but the result is likely to be different on different machines.
Here are some UTL examples:
// A resource whose definition may be reflected from example.com using IMOP imop:example.com/abc.def.Bar // A Java RMI service reachable at foo.com:1099 using the RMI protocol rmi:foo.com:1099/myobj // A Meso class named app.Client loadable by the local Meso runtime meso:app.Client // The IUnknown interface in Microsoft COM system com:00000000-0000-0000-C000-000000000046 java:java.util.HashMap // A Java class named java.util.HashMap java:float // The Java primitive type "float" cts:UInt64 // The type "UInt64" in the Common Type System mime:text/html;charset=utf-8 // The MIME type for a HTML document
IMOP is a TCP-based protocol similar to HTTP. The primary difference between IMOP and HTTP is how they interact with a remote resource. HTTP is designed to get a copy (i.e., a representation) of a remote resource, whereas IMOP is designed to operate it remotely. The resource IMOP operates on is like an object instance in a software program. One may call methods on the object to alter its internal states, but the object itself cannot be transfered over the network.
The type definition of the object, such as the methods it supports, can be obtained by sending an IMOP reflection request "DESC" to the object. The object will describe itself by returning a machine-processable type descriptor. The format of the descriptor subjects to content-type hand shaking between the client and the object. There is a default JSON-based format defined by IMOP that all IMOP users must support to ensure interoperability.
In programming language world, the mechanism to reflect and interpret an unknown object and thereby manipulate it dynamically is commonly called metaobject protocol (MOP)1, which is usually a set of APIs. Our protocol provides similar functionalities to metaobject protocols, but it is a true network protocol operating on top of TCP, so we coined the name Internet Metaobject Protocol (IMOP).
In addition to object instances, IMOP also supports abstract data types, such as interfaces or structures. The following shows a hypothetical object, imop:twitter.com/public.Timeline, that depends on various kind of types. It also demonstrates how a client can recursively resolve the definition of an unknown UTL. The blue boxes in the figure are the exact content of IMOP messages, except their headers such as the content-size header are removed for brevity.
The Meso language is a strongly-typed object-oriented language aims to make network programming easy. Syntax-wise, Meso is very similar to Java. What makes Meso different is that the physical locations of various parts of a program, such as user-defined data types or object instances, can be served by multiple machines. One can directly reference a remote resource in a Meso program, and the Meso compiler will actively acquire its type definition from the network for type checking. The IMOP protocol enables the compiler to do so systematically and automatically. Programmers do not have to worry about how the network protocol work.
The Meso source code above creates a Meso class, meso:app.Client, that accesses the hypothetical imop:twitter.com/public.Timeline object described in Fig.1. At compile time, the Meso compiler will send reflection requests to twitter.com and api.org as shown in Fig.1 for type checking. As a result, whether the source code above can pass Meso compiler's type checking depends on the type descriptors returned from those two hosts, which might change over time and the programmer of this client program may not have the control of it. This is very different from conventional languages in that programmers usually have full control of how a program is compiled.
This might seems awkward at first, but such external dependency is actually natural for Internet applications, and we are doing similar things every day. For example, we can make a RESTful API call to a Twitter server, but we don't have the control of the API nor the Twitter server, which might also change over time. Similarly, we can put an image served by a remote web site into our own web page, but we don't have the control of the image content nor its availability either. This is the essence of the Internet; no one has the central control of it. Meso brings this decentralized world into the programming language level, making a program source code more "connected" to the Internet then ever before.
At runtime, the tline variable in Fig.2 will store the Timeline object's reference, which is its full UTL imop:twitter.com/public.Timeline. To invoke list(30) on the object, the Meso runtime will send an IMOP call request to twitter.com, as shown in Fig.3, and then store the returned array value in the tweets variable. Evidently, the data sent over the network for an IMOP call is as light weight as a RESTful operation. Unlike most RESTful operations, however, values passed by IMAP calls are all strongly-typed.
Now let's look at the server side. Fig.4 below is the Meso source code for the imop:twitter.com/public.Timeline object. To execute the code, the Meso runtime should be started in a passive mode, listening to incoming requests at port 90 (IMOP's default port) rather than starting from main() somewhere. The runtime will execute the Timeline object upon receiving a request to it.
Notice that the namespace declared in Meso is not just a name to avoid naming conflicts; it directly affects how the program should react to the outside world. The Timeline object in Fig.4 is defined under imop:twitter.com, making the object respond only to IMOP requests sent to twitter.com. As a result, the code would be useful only if it is actually executed at twitter.com. One may use wildcard patterns (such as "*") in the namespace statement to make the resource respond to multiple host names.
Fig.5 shows the Meso source code of the ITlimeline and Tweet. The Meso runtime at api.org will handle the IMOP reflection requests to these two data types.
As described earlier, the type scheme in a UTL represents the mechanism required to locate the data type, which may rang from network protocols (such as imop: or rmi:) to programming language runtimes (such as meso: or java:). Meso allows programmers any resource pointed by a UTL in a Meso program, so long as the Meso compiler and runtime support the UTL's type scheme. The supported schemes can be expanded with plugin modules. Fig.6 is a Meso program that uses a Java class to print the "Hello World!" message:
The ability to work with heterogeneous resources, especially program libraries written in other languages, enables Meso to integrate with existing systems smoothly. One may use Meso programs as a facade to current programs, handling strongly-typed IMOP communications, and then reconstructing requests to interact with backend systems. This is also why we coined the name "Meso" for the language: it sits "in the middle" between heterogeneous environments, bridging them together.
Today, the RESTful style operation is perhaps the most popular way to make programs interact over the Internet. However, people have little consensus on how to design RESTful APIs. Every site has its own unique way to provide services through a combination of HTTP methods, URL parameters, and text documents in formats like JSON or XML. Therefore, programmers often need to write custom adapters to serve and use RESTful APIs, handling lots of plumbing work themselves. This is costly and painful. Even though using RESTful APIs is simpler then using alternatives such as Web Services or CORBA, it is still no where as intuitive as making a native function call in a programming language.
The ad-hoc RESTful style cannot be the ultimate solution for Internet applications. There must be a better way. This is why we created the Global Program Grid paradigm. We want to give programmers a higher level of abstraction so that application logics can be separated from underlying connectivity concerns. Using the Meso language, accessing a remote service feels just as natural and intuitive as accessing a local one. Most underlying plumbing work is automated by the Meso compiler and runtime. Moreover, with the help of UTL and the IMOP protocol, the compiler can give network operations the same level of strongly-typed protection as that for local operations, helping programmers to discover potential errors and minimize development costs. We believe that Meso, IMOP, and UTL together can empower us to build sophisticated distributed applications that aren't practically feasible by current means.
Please check the about us page.