31.10.06. Namespace Packages in Python

Ian Bicking wrote a Zope 3 Critique a couple of weeks or so ago, partially in response to a critique by Jean-Marc Orliaguet. I’ve wanted to write a response of my own, but time has not allowed it. Now, I’d like to use a few posts to post my own responses to a few items.

The first point I’d like to address comes under headline 3, The importance of standards:

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.

Ugh. zope.formlib is far more “right” than zope_formlib. Granted, this is largely opinion. But man, do I love namespaces. zope_formlib looks like one of those crap-ass hacks and tricks used by the litany of languages who have no namespaces and have to fake it.

First off - I hate the underscore, and believe it should never enter package / module names. Mixed case package/module names are also evil. PEP 8 recommends this:

Modules should have short, lowercase names, without underscores. … Like modules, Python packages should have short, all-lowercase names, without underscores.

While I don’t follow PEP 8 too religiously, I’ve found my life to be generally better by trying to stay close to it. I believe that short lowercase names without underscores are a nice constraint, requiring one to think a little bit about what a module/package will entail and how it will be used. If it’s a module that will be reused frequently, it’s good to have a name that’s easy to remember and type.

At least we don’t see as much of the following any more:

from DocumentTemplate.DocumentTemplate import DocumentTemplate

ugh.

Finally, Zope 3 is a large system. I make fairly large systems using many of its pieces, some more than others. Some of those are quite nice to use from an import standpoint when one just imports the sub-package:

from zope import component, interface

from interfaces import IBar

class IFoo(interface.Interface):
    def newbar():
        """ returns 'ha!' """

class BarAdapter(object):
    interface.implements(IFoo)
    component.adapts(IBar)

    ...

That’s a trivial and nearly pointless example, but it’s a pattern I find myself using more and more. I’d be a much less happy mac if I had to do the following:

import zope_component
import zope_interface
import sqlalchemy_sql

Ugh. Why not just introduce crap like ‘require’ and ‘use’ and leave this modularism behind?

There has been one problem, historically, with Python’s packages: unlike Perl, Ruby, Java, etc, the namespaces in Python are based exclusively on filenames and file system hierarchies. That has meant that a “namespace package” like zope.* would have to include everything. It couldn’t be distributed and used as smaller chunks easily, whereas if this were Java the packages/modules would use the ‘package’ keyword:

package org.zope.component;

But now SetupTools allows one to break these pieces up and distribute them separately while still getting the organizational and conceptual benefits of big hierarchical namespaces.

30.10.06. Simple Nuggets - Recent Interests in Seaside, Io, and more

I know that I haven’t posted much lately. I do have a couple of long draft pieces saved that I haven’t had time to finish. I don’t know if I’ll get back to them, but I’ll try.

I’ve been looking at a lot of different things recently, looking for new inspirations, tools, and/or chances to widen my understanding. I find myself growing increasingly fond of a couple of things in particular: Seaside on the web development side, and Smalltalk, Scheme/LISP, Io, and Javascript (particularly with the Prototype.js library) on the programming language side.

Seaside interests me on many levels. I’ve been staring at it with a lustful eye for some time now. There is definitely a place for heavily stateful web apps. Seaside and WebObjects make this a part of their core, where a developer can make an application in a style that is more like a desktop application: less dealing with sessions, freedom from the typical request-response cycle, etc.

But Seaside is more than continuations and callbacks. I love how you generate HTML in it: NO TEMPLATES!!! In a post titled “Turtles All The Way Down”, Ramon Leon writes:

Seaside lets me work in Smalltalk, at every level, all the way from programmatic generation of the HTML and Javascript to configuration of the application. No HTML, XML, XSLT, or SQL is necessary to build a web application, just simple, pure Smalltalk. Programming’s never been more fun!

I’ve made some in-house tools that get us closer to that goal when using Zope 3 and Python. I’ve started to hate template languages again. Well - I don’t mind using them for layout intensive work. But as I get more proficient with CSS, even that is changing.

[Edit: Moved side rant about Zope and Views and Templates out... This isn't the post for it]

It still stare lustfully at Seaside code, especially things like this very basic example:

renderContentOn: html
    html heading: count.
    html anchor callback: [self increase]; text: '++'.
    html space.
    html anchor callback: [self decrease]; text: '--'.

Ooo. Two links are made with anonymous functions that call self increase and self decrease respectively. There’s no “absolute URL”-ness going on. There’s no “how do I make it so that increase can be called through the web?”. No exposure decorator. No seven lines of XML code each for ‘increase’ and ‘decrease’ to be made into separate views. And no template. Just a solid binding between a link on a form and real code.

Seaside is a testament to the power of Smalltalk. People think that Seaside is all about continuations, and if they get just that part down, they’ve made something to compete. But it’s more than that: Seaside is a tool for building web applications in pretty much the same way one makes a desktop application. It’s not the tool or style for every job, but it definitely has its place.

In a recent bit of work we've done in Zope 3, I would have loved to have something like Seaside, especially for the checkout process. I've tried to engineer that process as well as I could, with extra preconditions and redirectors on pages to ensure that all desired information is supplied (ie - so that one can't jump from step 1 to step 4). With Seaside I could have encompassed the in a WATask component, expressing the checkout workflow as normal Python code: while shippingAddressRequired and (not order.shippingAddress): yield self.askForShippingAddressForm() (or something like that). The shopper could never accidentally (or purposefully) get past that point without supplying the right information. Doing this with preconditions, sessions, hidden form fields, cookies, etc, is all possible. But it can be a lot more code overhead.

Back to the other interests listed, really quickly: I’ve used LISP on very rare occasions (for customizing EMacs, basically, back in the day). I’ve never quite understood the appeal that LISP / Scheme have for some people until recently. While I enjoy and will probably continue to work in general purpose languages like Python, I’ve started to grow fond of these languages that are built on very simple precepts. Smalltalk has practically no syntax: it’s all messages. And I really like that Squeak is written in itself - there’s just something impressive about that. On a related topic, I checked on the progress of PyPy and was very impressed. Like Squeak, which has a small subset-of-smalltalk-to-C translator for generating the core pieces from Smalltalk itself, PyPy is Python written in Python, with translators to lower-level languages.

Regarding Scheme, I found a Scheme translator for Smalltalk and have spent a small amount of time playing with it this weekend. I came away impressed with how easy it is to parse and process Scheme, and how easy it is to implement it and its primitives in quite easily readable Smalltalk. The “everything is a list” (‘car’ and ‘cdr’) power finally came through to me as I browsed through the Smalltalk code to see how things that are keywords and operators in other languages (‘+’, ‘if’, etc) were implemented by just using car and cdr (the head and remainder of any list/pair, on which all things are based).

I’ve also become very interested in prototype-based programming. With prototype based programming, one has Objects but without classes and metaclasses and on and on. I’ve known about prototype based programming for some time, but I’ve only recently started to appreciate it. It’s radically simple. Looking around at Prototype based languages, I came across the relative newcomer Io. Io has no keywords - which, again, I find quite interesting and provocative. And powerful. It’s message based, which I like, and it has no classes. You just clone something to make something else. A simple object example from the sample code page:

Account := Object clone do(
    balance := 0
    deposit  := method(v, balance = balance + v)
    withdraw := method(v, balance = balance - v)
    show := method(writeln("Account balance: $", balance))
)

myAccount := Account clone
myAccount show
"Depositing $10\n" print
myAccount deposit(10)
myAccount show

Oh yeah - and the minimalist in me swoons over its web site.

There it is - a scattering of a portion of the thoughts that occupy my brain when I have the chance to take a breath at work.