views:

486

answers:

4

I recently discovered metaclasses in python.

Basically a metaclass in python is a class that creates a class. There are many useful reasons why you would want to do this - any kind of class initialisation for example. Registering classes on factories, complex validation of attributes, altering how inheritance works, etc. All of this becomes not only possible but simple.

But in python, metaclasses are also plain classes. So, I started wondering if the abstraction could usefully go higher, and it seems to me that it can and that:

  • a metaclass corresponds to or implements a role in a pattern (as in GOF pattern languages).
  • a meta-metaclass is the pattern itself (if we allow it to create tuples of classes representing abstract roles, rather than just a single class)
  • a meta-meta-metaclass is a pattern factory, which corresponds to the GOF pattern groupings, e.g. Creational, Structural, Behavioural. A factory where you could describe a case of a certain type of problem and it would give you a set of classes that solved it.
  • a meta-meta-meta-metaclass (as far as I could go), is a pattern factory factory, a factory to which you could perhaps describe the type of your problem and it would give you a pattern factory to ask.

I have found some stuff about this online, but mostly not very useful. One problem is that different languages define metaclasses slightly differently.

Has anyone else used metaclasses like this in python/elsewhere, or seen this used in the wild, or thought about it? What are the analogues in other languages? E.g. in C++ how deep can the template recursion go?

I'd very much like to research it further.

+6  A: 

To answer your question: no.

Feel free to research it further.

Note, however, that you've conflated design patterns (which are just ideas) with code (which is an implementation.)

Good code often reflects a number of interlocking design patterns. There's no easy way for formalize this. The best you can do is a nice picture, well-written docstrings, and method names that reflect the various design patterns.

Also note that a meta-class is a class. That's a loop. There's no higher level of abstractions. At that point, it's just intent. The idea of meta-meta-class doesn't mean much -- it's a meta-class for meta-classes, which is silly but technically possible. It's all just a class, however.


Edit

"Are classes that create metaclasses really so silly? How does their utility suddenly run out?"

A class that creates a class is fine. That's pretty much it. The fact that the target class is a meta class or an abstract superclass or a concrete class doesn't matter. Metaclasses make classes. They might make other metaclasses, which is weird, but they're still just metaclasses making classes.

The utility "suddenly" runs out because there's no actual thing you need (or can even write) in a metaclass that makes another metaclass. It isn't that it "suddenly" becomes silly. It's that there's nothing useful there.

As I seed, feel free to research it. For example, actually write a metaclass that builds another metaclass. Have fun. There might be something useful there.

The point of OO is to write class definitions that model real-world entities. As such, a metaclass is sometimes handy to define cross-cutting aspects of several related classes. (It's a way to do some Aspect-Oriented Programming.) That's all a metaclass can really do; it's a place to hold a few functions, like __new__(), that aren't proper parts of the class itself.

S.Lott
I respect your points. I shouldn't have equated metaclasses as patterns/roles but just implementations of them.But avoiding formalisation because it might be hard? Are classes that create metaclasses really so silly? How does their utility suddenly run out? Even metaclasses exhibit similarities.
@mike.amy: by "hard" I meant incomprehensible. Not "a little challenging". It's very difficult -- sometimes impossible -- to disentangle a number of well-thought-out design patterns into formalisms. Some good design decisions are habits and hard to formalize.
S.Lott
+8  A: 

This reminds me of the eternal quest some people seem to be on to make a "generic implementation of a pattern." Like a factory that can create any object (including another factory), or a general-purpose dependency injection framework that is far more complex to manage than simply writing code that actually does something.

I had to deal with people intent on abstraction to the point of navel-gazing when I was managing the Zend Framework project. I turned down a bunch of proposals to create components that didn't do anything, they were just magical implementations of GoF patterns, as though the pattern were a goal in itself, instead of a means to a goal.

There's a point of diminishing returns for abstraction. Some abstraction is great, but eventually you need to write code that does something useful.

Otherwise it's just turtles all the way down.

Bill Karwin
+1 for turtles!
Seth
+1  A: 

The class system in Smalltalk is an interesting one to study. In Smalltalk, everything is an object and every object has a class. This doesn't imply that the hierarchy goes to infinity. If I remember correctly, it goes something like:

5 -> Integer -> Integer class -> Metaclass -> Metaclass class -> Metaclass -> ... (it loops)

Where '->' denotes "is an instance of".

Rafał Dowgird
Thanks, some other people mentioned smalltalk.I will have to dig out me squeak VM and compare smalltalk's metaclasses to python's.
+2  A: 

During the History of Programming Languages conference in 2007, Simon Peyton Jones commented that Haskell allows meta programming using Type Classes, but that its really turtles all the way down. You can meta-meta-meta-meta etc program in Haskell, but that he's never heard of anyone using more than 3 levels of indirection.

Guy Steele pointed out that its the same thing in Lisp and Scheme. You can do meta-programming using backticks and evals (you can think of a backtick as a Python lambda, kinda), but he's never seen more than 3 backticks used.

Presumably they have seen more code than you or I ever has, so its only a slight exaggeration to say that no-one has ever gone beyond 3 levels of meta.

If you think about it, most people don't ever use meta-programming, and two levels is pretty hard to wrap your head around. I would guess that three is nearly impossible, and the that last guy to try four ended up in an asylum.

Paul Biggar