The book contains an explanation of what a metaobject protocol is, why it is desirable, and the de facto standard for the metaobject protocol supported by many Common Lisp implementations as an extension of the Common Lisp Object System, or CLOS.[1] A more complete and portable implementation of CLOS and the metaobject protocol, as defined in this book, was provided by Xerox PARC as Portable Common Loops.[2]
The book presents a simplified CLOS implementation for Common Lisp called "Closette", which for the sake of pedagogical brevity does not include some of the more complex or exotic CLOS features such as forward-referencing of superclasses, full class and method redefinitions, advanced user-defined method combinations, and complete integration of CLOS classes with Common Lisp's type system. It also lacks support for compilation and most error checking, since the purpose of Closette is not actual use, but simply to demonstrate the fundamental power and expressive flexibility of metaobject protocols as an application of the principles of the meta-circular evaluator.[3]
In his 1997 talk at OOPSLA, Alan Kay called it "the best book anybody's written in ten years", and contended that it contained "some of the most profound insights, and the most practical insights about OOP", but was dismayed that it was written in a highly Lisp-centric and CLOS-specific fashion, calling it "a hard book for most people to read; if you don't know the Lisp culture, it's very hard to read".[4][5]
In computer science, a metaobject is an object that manipulates, creates, describes, or implements objects (including itself). The object that the metaobject pertains to is called the base object. Some information that a metaobject might define includes the base object's type, interface, class, methods, attributes, parse tree, etc. Metaobjects are examples of the computer science concept of reflection, where a system has access (usually at run time) to its own internal structure. Reflection enables a system to essentially rewrite itself on the fly, to alter its own implementation as it executes.[1]
A metaobject protocol (MOP) provides the vocabulary (protocol) to access and manipulate the structure and behaviour of systems of objects. Typical functions of a metaobject protocol include:[2]
Metaobject protocol is contrary to Bertrand Meyer's open/closed principle, which holds that software object systems should be open for extension but closed for modification. This principle effectively draws a distinction between extending an object by adding to it, and modifying an object by redefining it, proposing that the former is a desirable quality ("objects should be extensible to meet the requirements of future use cases"), while the latter is undesirable ("objects should provide a stable interface not subject to summary revision"). Metaobject protocol, by contrast, transparently exposes the internal composition of objects and the entire object system in terms of the system itself. In practice, this means that programmers may use objects to redefine themselves, possibly in quite complex ways.
Furthermore, metaobject protocol is not merely an interface to an "underlying" implementation; rather, through metaobject protocol the object system is recursively implemented in terms of a meta-object system, which itself is theoretically implemented in terms of a meta-metaobject system, and so on until an arbitrary base case (a consistent state of the object system) is determined, with the protocol as such being the recursive functional relationship between these implementation levels.
Implementing object systems in such a way opens the possibility for radical discretionary redesign, providing deep flexibility but introducing possibly complex or difficult-to-understand metastability issues (for instance, the object system must not destructively update its own metaobject protocol - its internal self-representation - but the potential destructiveness of some updates is non-trivial to predict and may be hard to reason about), depending on the recursive depth to which the desired modifications are propagated.[3] For this reason, metaobject protocol, when present in a language, is usually used sparingly and for specialised purposes such as software that transforms other software or itself in sophisticated ways, for example in reverse engineering.[4]
When compilation is not available at run-time there are additional complications for the implementation of metaobject protocol. For example, it is possible to change the type hierarchy with such a protocol but doing so may cause problems for code compiled with an alternative class model definition. Some environments have found innovative solutions for this, e.g., by handling metaobject issues at compile time. A good example of this is OpenC++.[5]The Semantic Web object-oriented model is more dynamic than most standard object systems, and is consistent with runtime metaobject protocols. For example, in the Semantic Web model classes are expected to change their relations to each other and there is a special inference engine known as a classifier that can validate and analyze evolving class models.[6]
The first metaobject protocol was in the Smalltalk object-oriented programming language developed at Xerox PARC. The Common Lisp Object System (CLOS) came later and was influenced by the Smalltalk protocol as well as by Brian C. Smith's original studies on 3-Lisp as an infinite tower of evaluators.[7] The CLOS model, unlike the Smalltalk model, allows a class to have more than one superclass; this raises additional complexity in issues such as resolving the lineage of the class hierarchy on some object instance. CLOS also allows for dynamic multimethod dispatch, which is handled via generic functions rather than message passing like in Smalltalk's single dispatch.[8] The most influential book describing the semantics and implementation of the metaobject protocol in Common Lisp is The Art of the Metaobject Protocol by Gregor Kiczales et al.[9]
Metaobject protocols are also extensively used in software engineering applications. In virtually all commercial CASE, re-engineering, and Integrated Development Environments there is some form of metaobject protocol to represent and manipulate the design artifacts.[10][11][12]
A metaobject protocol is one way to implement aspect-oriented programming. Many of the early founders of MOPs, including Gregor Kiczales, have since moved on to be the primary advocates for aspect-oriented programming. Kiczales et al. of PARC were hired to design AspectJ for Java, a language which does not possess a native metaobject protocol.
I am new to the Groovy programming language and I am trying to fully understand the dynamic nature and capabilities it has. What I do know is that every class created in Groovy in its most basic form looks like this (implements GroovyObject and extending java Object).
Groovy object also contains a MetaClass that extends MetaObjectProtocol. It is this class hierarchy that provides some of Groovy's dynamic capabilities. This includes the ability to introspect itself (getProperties,getMethods) or intercept methods (invokeMethod,missingMethod).
Now that have some of that out of the way we can get to the meat of this question. When someone or a book refers to the "Metaobject Protocol" in Groovy are we talking about a specific class or a collection of things. I have hard time grasping something that isn't defined or set in stone. One of my books defined it as
A protocol is a collection of rules and formats. The Meta-Object-Protocol (MOP) is the collection of rules of how a request for a method call is handled by the Groovy runtime system and how to control the intermediate layer. The "format" of the protocol is defined by the respective APIs,
I also have Venkat's Programming Groovy 2 book and in it there is a diagram that defines this method lookup process. So I am guessing this is the rules of how we request a method (at least a POGO, I understand a POJO is different).
Anyways I think I am going down the right path but I feel like I am still missing that "ahhhaa" moment. Can anyone fill me in on what I am missing? Or at the very least tell me my ramblings here made some sort of sense :) Thank you!!
This is the answer. "The Meta-Object-Protocol (MOP) is the collection of rules of how a request for a method call is handled by the Groovy runtime system and how to control the intermediate layer." Once you understand the process a method call goes through and the API that comes with it I think it all makes sense. I was just over thinking it all. Thanks!!
Pardon my ignorance, but What is a Metaobject protocol, and does Ruby have one? If not, is it possible to implement one for Ruby? What features might a Metaobject protocol possess if Ruby was to have one?
To be more specific, it abstracts the components of an object system (classes, object, methods, object attributes, etc.). These abstractions can then be used to inspect and manipulate the object system which they describe.
It can be said that there are two MOPs for any object system; the implicit MOP and the explicit MOP. The implicit MOP handles things like method dispatch or inheritance, which happen automatically as part of how the object system works. The explicit MOP typically handles the introspection/reflection features of the object system.
All object systems have implicit MOPs. Without one, they would not work. Explicit MOPs are much less common, and depending on the language can vary from restrictive (Reflection in Java or C#) to wide open (CLOS is a perfect example).
If you look closer to the definition, youll see that Ruby does have a MOP. Is it like the one in CLOS? No, CLOS is a meta-circular MOP which is great (I'd even say genius), but it's not the one true way, take a look at Smalltalk. To implement a (let's say basic) MOP all you need is to provide functions that allow your runtime to:
b1e95dc632