Thursday, March 16, 2006

A hypothesis on why Pythonistas reinvent wheels

Well, maybe the title's more inflammatory than need be. This post is kind of a follow-up to Three Reasons You Shouldn't Write Your Own Web Framework, but it's a little broader than that.

My hypothesis is that Python has two "things" that appear together in few (if any!) other languages right now, and that the combination of these ingredients makes the proliferation of web frameworks (and libraries, and RSS readers, and wikis, etc....) nearly unavoidable.

Python has power



First off, Python is a powerful, expressive language. Sure, the Lispers out there deride its lack of macros, Rubyists bemoan its "impure OO", and so on. But Python is expressive enough. Enough to lower the amount of pain it inflicts upon programmers to where some would rather build a framework/library that's just right instead of grabbing something else that's out there. It's just so stinkin' easy to code up something quickly that will do exactly what you want. (Well, almost what you want, and you know how to avoid those bugs, anyway. ;-) )

But there are other languages that are more expressive, concise, "powerful." Why have they, too, not embarked upon the path of infinite diversity?

Python has programmers



Python is one of the most widely-used dynamic languages in the world today. Yes, Perl is more widely used. [Edit 4/1/07: In my completely uninformed opinion as someone who has never used Perl for anything even remotely serious,] Perl also makes it very easy to get yourself in trouble very quickly when building a large system. Not that it can't be done. Just that it kind of fails the "powerful" criterion above. Ruby is "getting there," or it may already have surpassed Python's popularity (hard to know for sure with such scientific measurements as "# of Google search results", "# of new books", "# of SourceForge/FreshMeat projects", etc. But Ruby has not had the time to develop the same critical mass of programmers with a hankering to build their own framework. Haskell, ML, Smalltalk, and so forth just don't have the base, either. Lispers built quite a few frameworks/libraries back in the day, but these were mainly in the realm of AI, so we won't hear much about them until AI comes back in vogue.

What to do?



I can't say I really know. After seeing Ian's tutorial on building your own WSGI framework, I see the allure. Working in academia, I also feel the urge to build upon prior research. Maybe it's the nature of the beast (having a widely-used, expressive language). What do you think?

Monday, March 06, 2006

TG Admin Interface (part II)

Well, the week was less-than-productive on the automated TG admin pages front. I did manage to extract the CRUD code from the model class, however. Here is the (new) code to create an admin page for a given SQLObject model:


import model
from crud import crudbase, fields

class DistributionCenterView(crudbase):
modelClass=model.DistributionCenter
displayName='Distribution Center'
fields=fields('name', 'note',
'address.street1', 'address.street2',
'address.city', 'address.state', 'address.zip',
'stores', 'trucks')
key='name'

this is for the following SQLObject model:

class DistributionCenter(SQLObject):
def destroySelf(self):
self.address.destroySelf()
SQLObject.destroySelf(self)

name=StringCol(default=uniqueValue('DistributionCenter', 'name', 'ctr'),
alternateID=True)
note=StringCol(default='')
address=ForeignKey('Address', default=newAddressID, cascade=False)
stores=MultipleJoin('Store')
trucks=MultipleJoin('Truck')

The resulting list view looks a little like this (simplified a bit for blogger):








































Name Note Street1 Street2 City State Zip Stores Trucks

Edit
Delete
Dist Ctr A A note on dca 123 Main Street Marietta GA 30062 Home Dep 3 SXG 456,ABC 123

Edit
Delete
Center 2 Another Center 456 Beechwood Ave. Marietta GA 30067 Store Num 1,store_2 333 HFF

As you can see, foreign keys and multiple joins are handled, as well as columns from foreign tables (via the "address.street1..." stuff). I'm still working on cleaning things up, but if this code would be a useful starting point for you, drop me a comment and I'll email you a copy. Alternatively, if there are several people interested, we'll set up a project on SourceForge.