In Plone, "is contained within", "is an instance of", and "is a subclass of" keep getting all jumbled up and blurred together. Not to mention re-invented five times over:
- Instances are instances of Plone types which are instances of Python classes.
- The templating system looks capable of sub-classing behaviour.
- CSS style-sheets cascade.
- Zope (which Plone runs on) has something called ZClasses, which I think are web-editable classes. Like Python classes, but you build them using the Zope management interface.
There are other examples. It's a big system.
Be nice to have just one mechanism. Why didn't they?
A lot of the extra layers of abstraction are non-programmable, and have a web-based configuration interface. This serves to document a lot of the options. And this is a very useful thing, because the options are necessarily complex. User-interface options, you must be able to tweak a lot of such options, or the interface will suck.
Seems to me the answer would be to keep the web interface, but store those options as python code. Python is good at introspection, this shouldn't be hard.
There's a trap here: boilerplate code. Once you start generating code, it's tempting to drop a whole lot of cruft in. This makes the resultant code confusing and unreadable. To avoid this, some rules:
- All generated code must be declarative, not procedural. Not even an init() function. The server can load the module and introspect it.
- As much as possible should be inherited from base classes, not inserted by the code generator. Only choices that override the base class should be inserted.
- Minimize import statements.
Another thing that would be nice: the web-interface for customizing subclasses should be declared in the base class. Seems a logical place to put it.
A possible good reason for re-inventing inheritance is a desire for a form of meta-inheritance. For example, you may wish to customize the base class of some whole family of classes. A paradigmatic example of this is re-skinning a web-site.
Kudos to Plone/Zope for identifying the problem, but I don't like their way of solving it. The Zope "acquisition" system, where objects inherit properties from their container, is particularly bad. Nevertheless, such systems as there are in Plone/Zope give it a lot of its power and customizability.
I guess I should confess, Aether has something very much like acquisition, and with some of the same problems.
It might be better to change the Python language somehow. I suspect this is a complex topic.
Another source of complexity in Plone/Zope is the distinction between filesystem and database. Python code largely lives on the filesystem. Zope objects (web pages, etc) live in the database. It's something I purposely avoided when designing Aether. I think that Aether's way, if implemented carefully, is better... but may need a good filesystem (eg ReiserFS) to scale well.