dynalang.org is currently the home of the generic metaobject protocol specification for dynamic programming languages on the JVM. If these words don't mean anything to you, don't worry - chances are you are not involved in business of actually building runtime environments for dynamic programming languages. Such runtime environment builders are our sole target audience at the moment, although we hope to eventually expand the focus to a broader range of topics involving dynamic languages - both creation and usage, both on JVM and CLR.

The JVM Dynamic Languages Metaobject Protocol Library

This library aims to make it possible for objects created by a runtime for one dynamic language to be passed to and manipulated by a different dynamic language, running within the same JVM. More generally, it aims to provide a facility where an arbitrary system (usually a language runtime) can intuitively manipulate any arbitrary object model built atop of Java objects (usually the native object model of some other language).

Basically, it provides a unified mechanism that all dynamic languages on the JVM can use to inter-operably manipulate their own objects as well as objects from any other language that also uses this mechanism.

It strives to achieve this goal not by defining "One True Object", a single interface to be implemented by all Java objects that represent objects of the dynamic languages in the JVM, but rather by providing an extensible metaobject protocol (MOP) mechanism, as first formulated in the "In-process cross-language object interaction: adapters or navigators?" article. The idea is to completely throw away the idea of a dedicated interface on objects themselves, and having to wrap foreign objects into adapter objects that expose the expected interface. Instead, the operations on objects themselves are encapsulated behind MOP objects (you can also think about them as being the "navigators" and "manipulators" for the objects they know about), with usually only a single MOP required per language implementation.

The basic usage difference is that a dynamic language runtime will retrieve a property on an object not by using code like this: ((MyDynamicInterface)obj).get("foo"); but rather it will use a MOP: metaobjectProtocol.get(obj, "foo");

The real strength of the approach lies in extensibility and pluggability of MOPs. MOPs can be easily composed, so if you compose your language's native MOP with other languages' MOPs, your code will be able to natively manipulate those other languages' objects. You can have a MOP for DOM objects as well to natively add XML manipulating abilities into your languages. Finally, a JavaBeans MOP is provided as standard component in the library - you can add it as the last element of your composite MOP so that your language can manipulate any POJO directly if no other MOP recognizes the object. Full range of Java amenities, including optimized runtime resolution of overloaded methods and support for JDK 1.5 variable arguments is available.

The secret of composability is MOPs ability to declare it has no authority to perform an operation on an object. When an operation is attempted in a composite MOP, all its element MOPs will be attempted in turn while they claim no authority for it. Only when one MOP either performs the operation or authoritatively decides it must fail is the operation outcome final. Note that the authority declaration is very fine-grained: it is per operation and per object. It is therefore much more versatile than the wrapper interfaces approach: when using interfaces, a wrapper class must decide up-front which interfaces to implement on the object. A MOP can decide based on the actual state of the object whether it can perform an operation. This can also be handily used to extend any objects with language specific meta-properties. Since the API allows any object, not just strings, to be used as property identifiers, it is easy to use implementation-private objects as property IDs for things like ECMAScript "prototype" property and similar. A theoretical ECMAScript MOP would thus answer the get and put requests for the prototype property of a POJO, but would claim no authority for get and put requests for other properties, letting those fall through to the JavaBeans MOP.