(If you don't care about Zope, you can probably skip this entire post.)

There was a small bit of controversy in the Zope community a while back when Nuxeo announced they were switching from Zope and Python to Java. Nuxeo has been using Zope for a long time, and has been an active part of that community, so this was a fairly major defection. Jean-Marc Orliaguet wrote a critique of Zope which is notable because of how familiar he is with Zope from a technical view, and because as an active member of the community he is somewhat invested in the choices Zope has made. It doesn't read like a condemnation to me, just a critique, though I think some people felt otherwise. (correction: I had previously said that Jean-Marc was associated with Nuxeo, which he isn't)

I don't know Zope that well, though Plone is core to TOPP and so I've been getting a lot more exposure to that environment. I've also been at least aware of many of the techniques they're using, though not how those work in practice (having not practiced them), so Jean-Marc's critique was very interesting to me. And it echos some of what I've been thinking.

1) The importance of the IDE This is a long-standing conflict, and I don't have anything to add to it.

2) The importance of stable APIs This is a tricky one. Every project has to deal with this, and many projects deal with it poorly. Part of Jean-Marc's argument here is that Java makes it very clear what is public and what is not, and what is allowed for and what is not, and so at least it makes it very clear what should be stable and what doesn't need to be stable. I think this is a valid criticism. But Zope 3 is actually really good here because of their use of interfaces. They are pretty clear about what methods are required, what methods are public. I wish Python had some better conventions around this in general (mostly in terms of documentation), but interfaces are pretty decent. I'm not a fan of adaptation (more about that later), but I'd like to use interfaces more. I use them here and there, but just in the abstract as documentation. Unfortunately, documentation tools don't understand my interfaces. I don't have a way to declare what interfaces something implements. All sorts of other things. I wish zope.interfaces was a bit lighter, though maybe it is light enough. I actually want language-level support, so everyone could agree on the contentions and build tools around that. That said, using Five I find the stream of deprecation warnings over the top.

3) The importance of standards Here Jean-Marc argues that there's lots of code under the zope namespace that doesn't belong there. It's not stable enough, or its APIs aren't stable enough, or its design or architecture is not widely enough applicable or agreed upon. I personally don't care much about namespaces. Is zope.formlib any more "right" than zope_formlib ? Is it any more hierarchical? I don't think so. I have one namespace package, but it's kind of a historical accident. I wouldn't (and don't) put any more libraries under that namespace. Each library should stand on its own, so why create these hierarchies? People read too much into those namespaces, which is happening right here. As for standards, I agree this is important. In some way adaptation (uh, still more on that later) is a way of sidestepping standards. I think in general Python needs more standard building. Maybe that's true for Zope too, or maybe those standards should be inclusive of the wider Python world that includes Zope.

4) The Design Patterns In the abstract, this is about patterns being unnecessarily built into the environment. Relatedly: this post argues they should be in the language while this reaction says the opposite -- I actually agree with the first post, but in this case agree with Jean-Marc and the second post. I guess I am inconsistent. But what Jean-Marc actually talks about is specifically adapters and the Zope component architecture. Adaptation is a useful pattern for dealing with API changes. When you have two isomorphic but incompatible objects, adaptation works great. This happens when there's little API differences (e.g., mixedCase vs underscore_seperated ). It starts to become a bit of a stretch at other times. And Zope 3 goes absolutely nuts with this, implementing all sorts of other patterns phrased as adaptation. This is complex and powerful, but in the bad way. From this, I've seen one-off interfaces that define no methods; interfaces that are just names; adaptation that works on multiple objects; adaptation that works on no object at all (adapting the ether); adaptation in place of attributes... it takes a nice but small idea and just keeps using it and using it until it's worn out and confused. I could go into specifics, but it might not mean much to lots of you, and I'd probably get the specifics wrong. If it quacks like a duck it's probably a duck. Lots of uses of adaptation don't quack; I don't know what they all are, but they aren't ducks.

5) The Component Architecture This is kind about plugins. A lot of the Zope component architecture is about plugins. It's fairly fine-grained; moreso than I think it needs to be. It's declarative, but with too many declarations. I think Setuptools' entry points solve a number of similar goals, but in a simpler way. There's still some issues that aren't well solved in either system (actually some of the exact same issues, like plugin activation), but I think Setuptools at least doesn't solve those problems in a simpler way.

6) ZCML is not XML To correct Jean-Marc: ZCML is XML. Maybe his real problem is that ZCML is fairly flat (maybe a bit too much like rdf). It's neither a nice syntax (it is after all XML), nor is it a compact XML language. But the Zope people know about this problem already. I don't think they are entirely sure how to fix it (maybe entry points will help), but I think everyone agrees it needs fixing. I guess the larger issue is that it's nice to declare things in Python code, but that only works if you import the Python code. So if you have something like an adapter sitting in some code, the system won't know that an adapter could be available if only it imported that code. An entry point version of this might be like: [zope.interface.adapters] package 1 = mypackage.adapter1 package 2 = mypackage.adapter2 (In this case package 1 doesn't actually mean anything, though maybe some use for that name could be found)

7) The Presentation Layer Zope views are confusing to me. I think I don't like them. I think this is probably my biggest issue with Zope 3 development. Zope seems unwilling to commit to being a web application environment. Everytime I see tutorials or descriptions about development in Zope 3, it always seems to begin with the model. "View", from what I can tell, is both "View" and "Controller" (when you are trying to be MVC about it), i.e., the Python controller and the template view. (This is just an explanation, I don't care about the terminology.) While I respect the distinction between view and model, what bothers me is that the view is an adaptation of the model. I think design should start at the ends, not the means. The model is just a "means". The "ends" is what the user sees -- the HTML, the template, the forms, the functionality. That's where application design should start. Admittedly, an experienced programmer can bang out a quick model pretty easily, and will do so quite quickly regardless of what the underlying architecture dictates. But I'd rather see a sloppy model that is refined later than a rigid UI built magically by some framework. I think Zope does a bit too much of the second. Perhaps because a number of Zope developers don't actually like HTML, and so want to avoid it through frameworks. I think they just need to get over it.