From: Danny O cuiv Date: 2009-05-21T03:38:05+09:00 Subject: Re: Superclass of eigenclass Rick Denatale wrote: > But that's just me, after all it's all just images caused by smoke and mirrors :-) Perhaps. But there's also the more mundane possibility that it's just inconsistent semantics and bad terminology. There seems to be two forces contributing to this. Firstly, the profusion of terms (many of which are clearly misnomers) is getting out of hand, and is unhelpful to newcomers. Secondly, many people still resort to referring to MRI runtime structures when discussing semantics even though Ruby is now being implemented on the JVM, on the CLR, on the Objective-C runtime and presumably elsewhere. There is now a clear need to be able to discuss semantics at a sufficient level of abstraction, i.e. purely in terms of what is revealed by the reflection API. If there are any inconsistencies or anomalies revealed by the API, then this should be addressed directly. The central point that I think should be made here is that per-instance behaviour has nothing to do with inheritance, per se. One obvious language rule will be that per-instance behaviour should take precedence over instance-common behaviour and one convenient way of implementing that is to snap an eigenclass into the chain between the instance and its class. But that implementation-specific runtime structure won't serve as a definition of the semantics for implementations that work differently. Take, for example, a "Ruby in the browser" (perhaps one already exists?) that translates onto the JavaScript object model. It would make perfect sense for this to implement per-instance behaviour as object properties. The class << obj syntax would then just be a way of manipulating the per-instance behaviour collectively. The only assumption being that method resolution is correctly (and hopefully efficiently) implemented. And the eigenclass would be purely a conceptual notion, existing only as several properties of an object, taken together. No problem whatsoever. It seems that the snapping of eigenclasses into the structure was intended to be a private implementation detail. Certain reflective methods were written in such a way as to skip over the eigenclasses, as though they were not to be regarded as part of the public (semantic) inheritance hierarchy. However, there were one or two leaks. For example, eigenclass.superclass reports the original class of the instance (in 1.9 at least). And, in a similar vein, the keyword super chains from an instance-specific method to a regular instance method. (As it happens, it transpires that this is convenient way of enabling interception.) Ideally, one would like to stem the leaks as far as possible without causing too much breakage of existing code. Here's a few conclusions I've come to. I'd be interested to hear what others think. (i) The correct way to present method resolution is the way Flanagan/Matz do on page 258 of their book, i.e. as an algorithm. It's simple, intuitive and easy to remember. Ruby implementations are free to implement this algorithm any way that's convenient (and fast) in their given context. The wrong way to present method resolution is the Pickaxe approach of using diagrams from MRI's runtime structure. Apart from not being portable (which will become a bigger and bigger problem), it's backwards. That runtime structure exists like that in order to support certain desired semantics. So deriving the semantics from the structure is neither here nor there. Just state them up front. (ii) The keyword super should just be defined to work according to the method resolution algorithm, not the inheritance hierarchy. This is what happens at the moment, so it's just a formalising of the de facto situation and doesn't break anything. This would preserves the convenient chaining from a per-instance method to the regular instance method and makes it clear that there are potentially lots of other useful chaining opportunities. As Gary pointed out to David earlier in this thread, the sequence of classes produced by the method resolution algorithm is different from the inheritance hierarchy because of module mixin and eigenclasses. (And in Ruby, module mixin is not inheritance, regardless of the similarity.) (iii) The superclass method should be defined to return Object for the eigenclass of a regular object. In other words, the original statement I alluded to from page 261 of RPL would now be true. The current situation (returning the class of the instance) is an implementation leak. I don't think there would be much breakage resulting from this and it cleans things up. (iv) In principle, class method resolution could also be defined purely by an algorithm, as a language rule, which would then not require explicit semantic inheritance to work. Lastly, the terminology situation needs to be addressed by the community. The term eigenclass is really spot on for a conceptual container for per-instance behaviour and it's great that RPL adopted it. The other terms are not acceptable synonyms; they are misnomers. (a) metaclass Even _why, in the 2005 piece that led to the widespread use of the term metaclass, acknowledged that the term was wrong: 'This definition doesn’t really work with Ruby, though, since "a class which defines a class" is simply: a Class'. The simplest way to illustrate this is to compare Smalltalk and Ruby. In Smalltalk, if you evaluate the expression "Integer class", you get "Integer class" (i.e. the same thing). The answer being the same as the question is an expression of the anonymous nature of the metaclass, but is read by a Smalltalk programmer as "the metaclass of Integer". In Ruby, if you evaluate the expression "Integer.class", you get "Class". Thus, even if the eigenclasses of class objects in Ruby play a similar role to metaclasses in Smalltalk, they are not metaclasses. By definition. (b) singleton class As pointed out in the "Ruby in the browser" example above, there is no need for the eigenclass to actually exist as a regular class, let alone have a single instance. Clearly then, the term singleton class would only be appropriate to some implementations and would consequently be a misnomer. While I'm at it, the term "singleton method" is also a misnomer. The term "singleton" derives from set theory. A singleton set is a set with one element. As such, the GoF pattern is a perfect fit. However, there is no singleton set anywhere in this situation (unless you get really silly in your choice of set). You can have many instances, each with many per-instance methods. The only appearance of the word "one" is on one side of the cardinality of an association (and not on the method side). For reasons of symmetry, eigenmethod is a far better term. Regards, Danny. -- Posted via http://www.ruby-forum.com/.