Talk:Metaclass

Page contents not supported in other languages.
From Wikipedia, the free encyclopedia

java.lang.Class[edit]

Is java.lang.Class a metaclass? —Preceding unsigned comment added by Wlievens (talkcontribs)

Not really; that's more related to introspection. It doesn't define how classes and their instances behave. All classes and instances behave the same in Java: they do what the JVM says. Java doesn't really have metaclassing. Jorend 16:12, 16 February 2006 (UTC)[reply]
The above answer is not correct. The definition is "a metaclass is a class whose instances are classes." In Java, all classes including java.lang.Class are instances of java.lang.Class. A good reference on this subject is Appendix A of Java Reflection in Action by Ira R. Forman and Nate Forman, Manning, 2005. The issue alluded to above is that Java Reflection API does not allow one to dynamically create classes or modify them.--Ira Forman 15:32, 20 December 2006 (UTC)[reply]
Calling a java.lang.Class object a class strikes me as a little weird, though. My view is that Class objects merely represent classes; they're not really classes. This view is supported by the docs. For example, the only place I can find java.lang.Class mentioned in the Java Language Specification [1] is here: "The method getClass returns the Class object that represents the class of the object." (Emphasis added.) Similarly, the javadoc for java.lang.Class says: "Instances of the class Class represent classes and interfaces in a running Java application. Every array also belongs to a class that is reflected as a Class object that is shared by all arrays with the same element type and number of dimensions." (Emphasis added again.) And there are Class objects, especially Void.TYPE [2], which I would argue clearly aren't classes. --Jorend 14:27, 7 January 2007 (UTC)[reply]
No, Jorend is correct. You cannot instantiate java.lang.Class into a class (as required by your definition sentence), let alone extend it (even if it were declared non-final; there simply isn't any metaclass functionality to extend). It is a tool for reflection, nothing more. --Piet Delport 11:02, 16 January 2007 (UTC)[reply]
Just because a class doesn't have a public constructor doesn't mean you cannot instantiate it. Many perfectly good classes don't have public constructors, like java.util.regex.Pattern or java.nio.ByteBuffer. However, you can still instantiate them through factory methods. The same thing is true of java.util.Class. You can instantiate it through Class.forName(), for example. Yes, that requires having an existing class file for it to load (which is a detail of the Java loading mechanism), but that still fits the description of being able to instantiate it. --208.80.119.67 (talk) 23:44, 14 July 2011 (UTC)[reply]
Gentleman, the definition of a metaclass is: "a metaclass is a class whose instances are classes." java.lang.Class meets this definition; consequently, it is a metaclass. Now there are two issues in your comments to discuss.
First, as Piet observed, one cannot instantiate java.lang.Class. This implies a huge weakness in the Java Metaobject Protocol. Programmers compensate for this weakness with many complex tricks played in specialized class loaders. If the Java MOP were sufficiently capable, such tricks would be unnecessary. However, this does not change the fact that by definition java.lang.Class is a metaclass.
Second, the definition of metaclass is part of a theory of reflection (a subset of the theory of programming languages) that is independent of specification of any particular programming language. The reason the JLS uses the word "represents" is that a Java class is a syntactic form written in the Java language. A class object is a representation of that syntactic form (and implies much about the meaning of that form). This sublty in wording of the JLS is required for languages that have reflection (i.e., where the semantics of the language is wholy or partially represected in the language itself). This issue has no bearing on the fact that java.lang.Class meets the definition of a metaclass.
BTW my home page (http://home.austin.rr.com/forman/ira/index.html) has two papers on JEM, my proposal to extend Java give java.lang.Class that capabilities that we all would like it to have.
Ira Forman 18:48, 17 January 2007 (UTC)[reply]
Ira wrote: "Gentleman, the definition of a metaclass is: 'a metaclass is a class whose instances are classes.' java.lang.Class meets this definition; consequently, it is a metaclass."
I accept the definition; I wrote it. Where your argument falls down is that the instances of java.lang.Class aren't classes.
Ira wrote: "The reason the JLS uses the word 'represents' is that a Java class is a syntactic form written in the Java language."
Nonsense. JLS consistently calls the syntactic form a "class declaration". --Jorend 16:14, 22 January 2007 (UTC)[reply]
"... the instances of java.lang.Class aren't classes." Sounds like a circular statement. --208.80.119.67 (talk) 22:47, 12 July 2011 (UTC)[reply]
There seems to be one major difference between Java's java.lang.Class and the metaclasses in Smalltalk, Objective-C, etc.: Class methods in those languages are simply instance methods of the class object. You can select the class object dynamically, and call a method on it like a method on any other object, and it will call the class method. Whereas, a Class object in Java only has the instance methods of the Class class; given a Class object you cannot simply call a method on it to access a static method of the class; you have to use reflection to do something similar. --208.80.119.68 (talk) 00:29, 1 May 2012 (UTC)[reply]

See Also[edit]

The See Also list is larger than the article. Can't it be trimmed? -- Mikeblas 03:37, 27 January 2006 (UTC)[reply]

Done. Next time, Wikipedia:Be bold! Jorend 17:53, 16 February 2006 (UTC)[reply]

Squeak freezes on double Metaclass instantiation[edit]

Just try to do this:

Transcript show: (Metaclass new new).

Squeak goes irresponsive and takes 100% CPU usage. Could someone please explain why this happens?

'cause the Metaclass has no class. Try comp.lang.smalltalk to get a fuller answer. The
actual interaction between the VM and OS causing the error is beyond the scope of this ::article.Mal4mac 18:39, 13 December 2006 (UTC)[reply]

Ruby?[edit]

As far as i can tell, the "Metaclasses in Ruby" reference does not actually describe metaclasses, but a different Ruby concept known as "singleton classes". Any objections if i go ahead and remove it? --Piet Delport 09:58, 12 January 2007 (UTC)[reply]

OK, i've removed it. --Piet Delport 10:20, 16 January 2007 (UTC)[reply]

Ruby has the Class class and every classes are instances of it[3] so I'm going to add it again. --Kusunose 10:34, 6 June 2007 (UTC)[reply]

That doesn't provide metaclass functionality: you can't subclass or otherwise extend it. (See the discussion about java.lang.Class above.) --Piet Delport 20:01, 6 June 2007 (UTC)[reply]

(sigh) Someone re-added Ruby to the list, with a comment about Ruby's metaclasses being the same as Smalltalk's. I find that pretty unlikely. If it can't be sourced, I'm going to remove it again. —Jorend (talk) 13:42, 2 April 2008 (UTC)[reply]

Someone should mention Ruby in the article. Regardless of whether Ruby has metaclasses, there is a very common perception that it does (google it) and it's worth addressing that in the article. Ruby's object model *is* in fact very similar to Smalltalk's so it's no surprise that someone would have added that to the article. Here's something I found by one of the more influential Ruby programmers-- Ruby doesn't have meta classes. You guys could expand on that and similar articles throughout the web. The more or less definitive book on Ruby is "The Ruby Programming Language" (written by Matz the creator of Ruby among others). Like Bini, the authors prefer the term "eigenclass" and use it throughout the text. In either case, the article right now isn't very well written. There is a lot of ambiguity, especially on the definition, which states that "a metaclass is a class whose instances are classes." That is exactly how Ruby's classes work, as Kusunose pointed out earlier. Piet counters that it isn't sufficient because it can't be subclassed or extended. If this is true, this belongs in the article, along with a proper citation. I will add a "Citation needed" tag and let those are more interested in language lawyer-ing figure it out. -- Solberg (talk) 23:08, 30 August 2009 (UTC)Solberg[reply]

Singleton classes in Ruby do inherit from class Class. In addition, a class is always an instance of its singleton class. Why are singleton classes, then, not considered metaclasses as well? Paul Brannan (talk) 15:43, 17 November 2009 (UTC)[reply]

..and?[edit]

What's the point of having this? What is it used for in real life? —Preceding unsigned comment added by 71.167.68.142 (talk) 01:50, 19 June 2009 (UTC)[reply]

Metaprogramming, for one thing. (This is not the only way metaprogramming can be done, though.) -- Solberg (talk) 23:09, 30 August 2009 (UTC)Solberg[reply]

slots in python code[edit]

Is there any reason for the assigning the __slots__ in the python code example? I know about the efficiency gain but that's not the point of this example. --138.246.2.200 (talk) 23:16, 20 September 2011 (UTC)[reply]

"Alternative definition" confusing, incomplete, or wrong[edit]

The "Alternative definition" is highly confusing.

  1. It says "The metaclass root is the class of the inheritance root", but doesn't define term "inheritance root". It seems to imply that "inheritance root" is always a class object? How do you determine whether something is the "inheritance root"?
  2. It says that "in the case of the latter two languages [Smalltalk and CLOS] care must be taken as to what is meant by class of in (1)". But it does not elaborate on what should be "meant by class of" for those languages. It says "Unfortunately, the introspection methods class (in Smalltalk) and class-of (in CLOS) are misleading here." But e.g. the class method in Smalltalk precisely reports the class of an object, and if your definition does not match, then it's your definition that needs to be modified.
  3. It says "Metaclasses are either explicit or implicit according to whether they are classes or not, respectively." and that "implicit metaclasses are supported by Ruby, Smalltalk-80 and Objective-C". However, I can assure you that metaclasses are classes in Smalltalk-80 and Objective-C. (Maybe you have a different definition for what "is a class"?)
  4. It says "By standard, the metaclass root is named Class." However, in Smalltalk-80, the "inheritance root" is Object, and thus the "metaclass root", which is defined as the class of the inheritance root, is Object class. However, Object class is not Class. Instead, Class is the direct superclass of Object class.
  5. It says "The metaclass root is simultaneously the instance root". What the hell is an "instance root"? "Root" implies some kind of hierarchy. For classes, there is the inheritance hierarchy. But what is the "hierarchy" for instances? — Preceding unsigned comment added by 50.193.52.113 (talk) 20:03, 19 December 2012 (UTC)[reply]
  6. How does this definition include/exclude languages like Java? Could the user simply claim that the Class object representing Object (i.e. Object.class) is the "inheritance root", and thus the Class object representing Class (i.e. Class.class) is the "metaclass root"? However, Java is not generally considered to have metaclasses. I believe that this has to do with the fact that "inheritance root" and "class of" are not well defined, as above.

-- 50.193.52.113 (talk) 20:44, 18 December 2012 (UTC)[reply]

  1. The term "inheritance root" is not defined – instead the page refers to another page, via the inheritance root link. This referred page is supposed to be dedicated to the subject. It at least lists the names of inheritance roots for all the mentioned programming languages: Smalltalk, Ruby, Python, Java, Scala, CLOS (as a dialect of Lisp), and Perl 5. Exact definition of the term is then given in eigenclass model on which the "alternative definition" is based.
  2. The main characteristics of the (possibly fictitious) canonical .class map is:
    • monotonicity: for every objects x, y, if x is an inheritance descendant of y, then x.class is an inheritance descendant of y.class,
    • independence on the implementation of infinite regress: the map should return an explicit named/nameable class, not an eigenclass, since eigenclass chains are conceptually infinite.
    The CLOS object model violates the monotonicity principle for some built-in classes (but it disallows user-created monotonicity breaks). As a consequence, the (CLOS's) class-of the inheritance root is the built-in-class which is not the highest metaclass since it is not an ancestor of e.g. the standard-class metaclass.
    The Smalltalk-80 object model (taking together with the introspection method named class) violates both principles. The violation of the second principle is typically "compensated" by terminological dialectics. In most of the Smalltalk literature, metaclasses are sometimes classes (this is what is usually explicitly proclaimed), sometimes not (usually implicitly). In the following statements, metaclasses are implicitly not classes:
    • Metaclasses are in one-to-one correspondence with classes.
    • Metaclass inheritance parallels class inheritance.
    • The Metaclass class is not a metaclass.
    • Metaclasses are exactly the Metaclass instances.
    • Each class has a name.
    In contrast, the Ruby programming language does not violate the above principles. The terminological dilemma is solved by distinguishing classes and Classes, the latter being (possibly indirect) instances of the Class class, the former being Classes without eigenclasses. This is in particular reflected in the semantics of the class introspection method. The differences between Ruby and Smalltalk in this respect are shown in the following table:
    Language Expression evaluates to
    Ruby Object.class the Class class
    Smalltalk-80 Object class the eigenclass of Object

    The "alternative definition" just follows the Ruby's approach since it allows cleaner description.

    I don't understand the utility of this fictitious .class map that you describe. Why does it have to return something "named"? You talk about the supposed problem of eigenclass chains being infinite. But that is a problem only because you are considering these convoluted fictitious eigenclasses; if you consider the actual "class-of" relationship in the various languages, they will only lead to a finite number of objects (although it can go into a cycle). I think it is much clearer to talk about (and people who come to this article would actually want to know about) the actual class-of relationship for each language, no matter if it leads to a named or unnamed class. --50.193.52.113 (talk) 01:29, 28 December 2012 (UTC)[reply]

    The utility of the (mostly) fictitious .class map is uniform description. The .class map provides a formally clean concept to which the programming languages can be compared. Deviations from the concept can be seen as implementation/design "quirks".

    In particular, the .class map allows the correspondence

    c = r.class

    between the inheritance root and the metaclass root. The correspondence applies as follows:

    Ruby Python Scala / Java Smalltalk-80 CLOS
    Inheritance root r BasicObject object Any/Object ProtoObject T
    Metaclass root c Class type Class Class class

    Given this, metaclasses are the inheritance descendants of c. If you only consider the table, without the .class map, then the definition is "widely acceptable" (w.r.t. established conventions) except for the single case of the Class class in Smalltalk-80 which is presumably not considered to be a metaclass in the Smalltalk literature. But even in this case, one can say that all strict descendants of c are metaclasses. (Note that this would not be possible if c was the Metaclass class or its eigenclass.)

    As already mentioned before, the Smalltalk-80 class method deviates from the canonical .class map in two respects. First, if x is a class (so that x is a descendant of the inheritance root but NOT a strict descendant of Class) then x class returns the eigenclass of x instead of – like in Ruby – skipping the eigenclass as well as all the ancestors that are eigenclasses and returning the first "real" class[1] which would in this case be constantly the Class class. Second, if x is an implicit metaclass (so that x is a strict descendant of Class) then x class "redirects" to the Metaclass – instead of following all the (possibly fictitious) ancestors of the fictitious eigenclass of x which would finally again result in "hitting" the Class class, just like in Ruby.

    The "alternative definition", being based on the eigenclass model (as known from Ruby), just prefers uniformity over particular conventions (such as the class method in Smalltalk-80). But perhaps it should be specific about why the class / class-of introspection methods of Smalltalk-80 / CLOS are considered "misleading". Hundblue (talk) 13:54, 28 December 2012 (UTC)[reply]

  3. This has been already explained in the previous point. Based on the eigenclass model introduced by Ruby, implicit metaclasses in Smalltalk-80 are Classes but not classes. The same holds for Objective-C, but just in abstract sense, since Objective-C does not have a single non-degenerated metaclass root.
  4. As indicated by the above table, the class of the Object class is the Class class – using the semantics of the eigenclass model. And, indeed, it is true that the eigenclass of the inheritance root is the only direct descendant of the Class class. (This eigenclass is obtained by evaluating ProtoObject class in Pharo or Squeak.)
  5. The core structure of an object model that support metaclasses has two fundamental relationships: the inheritance relationship and the instance relationship.[2] Both relations are hierarchical, in the latter case except for classes that are their own instances. But if the instance relationship is considered in the strict sense direct-instance-of (so that it equals the .class map, taken as a relation) then this relation forms a tree whose root is the fixpoint of the .class map ( x.class.class.class. … stops at this root).
    As a consequence, in addition to the inheritance root there is also an instance root which is simultaneously the metaclass root.
    My comment to the suggested term "hierarchy for instances": In an object model that supports metaclasses, the bare word "instances" should be avoided because it is synonymous to "objects" – every object is an instance of some class.
    There does not have to be a fixpoint. For example, in Smalltalk-80, the instance-of relationship ends in a cycle of 2 -- Metaclass class class is equal to Metaclass, but Metaclass class is not equal to Metaclass. So while it is true that (assuming the language has a finite number of objects) the instance-of relationship must end in a cycle, that cycle does not have to have a length of 1.
    Plus, neither member of this cycle (neither Metaclass nor Metaclass class) is the "metaclass root", as you say an instance root would be. --50.193.52.113 (talk) 01:29, 28 December 2012 (UTC)[reply]

    If you consider the canonical .class map, then there is always a fixpoint. This fixpoint is unique for Ruby, Python, Scala/Java, Smalltalk-80, and CLOS – it equals the metaclass root c (see the table in point 2). As mentioned above, the class method of Smalltalk-80 does not correspond to the canonical .class map. Instead, it corresponds to what can be called imposed actualclass map. This map has indeed a 2-element cycle you described.[3] Hundblue (talk) 13:54, 28 December 2012 (UTC)[reply]

  6. The definition also applies to Java/Scala provided that each class is identified with its "class object", so that e.g. Object.class (or classOf[Object]) is regarded as just an inconvenient reference to the class that is named Object. Such an identification is suggested by the introspection method named getClass. This method would presumably be named getClassObject if a distinction was considered worth emphasizing.
    This or similar approach is taken in the book Java Reflection in Action[4]. This book has a common co-author (Ira R. Forman) with the book Putting metaclasses to work which is a standard reference for the classic definition of a metaclass. The following are citations from the mentioned Java book:
    • In Java (…) all classes are objects.
    • Class is Java's only metaclass.

Hundblue (talk) 15:37, 24 December 2012 (UTC)[reply]

Examples: Do we really need so many?[edit]

This is more a general comment after looking at several wiki articles on OO, not that specific to this article per se although it applies here as well. I notice many of the OO articles do this, they talk in very language specific terms rather than first describing the general concepts and they jump fairly quickly to low level coding examples that will quickly lose anyone who doesn't know how to program. IMO, we should focus first on describing the concepts more and do so in a way that isn't specific to C++, Java, Smalltalk or any other language and then perhaps give an example. Examples seem to me (mostly) more appropriate for a technical manual not an encyclopedia anyway. MadScientistX11 (talk) 17:32, 27 December 2013 (UTC)[reply]

"Infinite chains" in Ruby?[edit]

The "In Ruby" section currently states " Consequently, eigenclasses form infinite chains. " I notice someone edited out a second sentence about how this leads to an infinite regress. I'm not even sure what "infinite regress" was supposed to mean there but it seems reasonable to take it out but I wonder WTF are these "infinite chains" anyway? I know nothing about Ruby but it's hard for me to imagine how any programming language can support infinity as a run time concept. Does anyone know what this means? Is it really supported by that reference and if so can we say it in a way that makes more sense? If no one replies I'm going to just be bold and delete that sentence completely. --MadScientistX11 (talk) 22:47, 2 December 2014 (UTC)[reply]

I just found this:

"But I've already told you: classes store methods. They're different. Now I know you're probably a bit confused wondering, "If a class is an object, but objects are built on classes, isn't there a big confusing infinite cycle here that you're not explaining?" No, there's not. I hate to break it to you, but a class isn't really an object. From Ruby's source code:"

http://ruby-metaprogramming.rubylearning.com/html/seeingMetaclassesClearly.html

So I'm removing that extra sentence about "infinite chains". --MadScientistX11 (talk) 23:28, 2 December 2014 (UTC)[reply]

  1. Eigenclass chains must be infinite as a consequence of the following three assumptions:
    • Uniformity (universality): Every object has an eigenclass.
    • Injectivity: Different objects have different eigenclasses. (This property is reflected by the eigen prefix, meaning own.)
    • Acyclicity: There are no cycles in eigenclass-of.
  2. ... how any programming language can support infinity as a run time concept – Infinity can be supported through lazy evaluation. This is exactly what is applied to Ruby's eigenclass chains.
  3. ... how this leads to an infinite regress – The term infinite regress has already been used in such circumstances. See e.g. the paper [5] (page 3) about Self or papers [6] [7] about ABCL/R. In the latter case the term infinite regression is used.

Hundblue (talk) 10:04, 3 December 2014 (UTC)[reply]


Python example[edit]

This section asserts that "In languages without metaclasses, these details are defined by the language specification and can't be overridden." This is oversimplified and incomplete. For example, while it has nothing approaching metaclasses, the C# language allows the layout of types to be customized using metadata supplied via the Struct Layout Attribute the usage of which is described on MSDN: "StructLayoutAttribute Class".

Aluan Haddad (talk) 21:47, 19 February 2015 (UTC)[reply]

The Struct class in Ruby[edit]

The Struct class in Ruby [8] is not a metaclass, despite having the new class method that creates classes. You can verify that classes created via this method are not instances of Struct.

The following code shows another example of a new method that returns a new class, yet the M object that responds to the method is not a metaclass (it is even a string):

  M = "Metaclazz"
  def M.new
    Class.new
  end
  A = M.new
  p [A, A.class]                # [A, Class]
  p [M, M.class]                # ["Metaclazz", String]
  A.is_a?(M) rescue p $!.class  # TypeError

Please stop vandalizing the In Ruby section.Hundblue (talk) 08:44, 4 May 2015 (UTC)[reply]

References[edit]

History[edit]

It would be useful to provide some history of the term/concept 'metaclass'. Who proposed the concept? Which language first implemented it? Who proposed the word? John Vandenberg (chat) 01:32, 23 July 2015 (UTC)[reply]

External links modified (January 2018)[edit]

Hello fellow Wikipedians,

I have just modified 2 external links on Metaclass. Please take a moment to review my edit. If you have any questions, or need the bot to ignore the links, or the page altogether, please visit this simple FaQ for additional information. I made the following changes:

When you have finished reviewing my changes, you may follow the instructions on the template below to fix any issues with the URLs.

This message was posted before February 2018. After February 2018, "External links modified" talk page sections are no longer generated or monitored by InternetArchiveBot. No special action is required regarding these talk page notices, other than regular verification using the archive tool instructions below. Editors have permission to delete these "External links modified" talk page sections if they want to de-clutter talk pages, but see the RfC before doing mass systematic removals. This message is updated dynamically through the template {{source check}} (last update: 18 January 2022).

  • If you have discovered URLs which were erroneously considered dead by the bot, you can report them with this tool.
  • If you found an error with any archives or the URLs themselves, you can fix them with this tool.

Cheers.—InternetArchiveBot (Report bug) 15:06, 26 January 2018 (UTC)[reply]

Smalltalk-80 metaclasses diagram thumbnail omits instanceof arrows but keeps instanceof labels floating in space.[edit]

Compare these two:  In the former, the "instanceof" labels are floating, labeling nothing.  In the latter we have instanceof arrows.

The Smalltalk-80 metaclass hierarchy as a UML diagram, as typically shown here, missing the instanceof arrows
The Smalltalk-80 metaclass hierarchy as a UML diagram, enlarged now shows the missing instanceof arrows

— Preceding unsigned comment added by 174.62.125.132 (talk) 16:25, 20 April 2018 (UTC)[reply]

C++ metaclasses[edit]

The page specifies that C++ metaclasses are planned for C++ 23, but I find no evidence that this is planned for release in this version. In particular, C++23 - cppreference.com makes no mention of metaclasses. Could someone confirm if this is indeed planned and undocumented, or just an error in this page ? 192.54.145.138 (talk) 12:24, 25 April 2023 (UTC)[reply]