Check Please!

I’d like to ask you, dear internet, for a reality check. Over the past two months I’ve been working on a little side project, and I’ve got it working to the point where I have to ask myself (and, by extension, you!) whether or not it’s worth the effort I’m putting into it.

It’s a web application framework called Kudzu.

It’s similar in spirit to Ruby on Rails, but with several important differences that I’ll outline in this entry. It is by no means complete or ready for general use — among other things, half of the objects aren’t implemented, and it doesn’t leak memory so much as spew memory in every direction — but the most basic features work, and I think that the most basic features are also the most alluring.

Kudzu is scripting language agnostic. I’ve described Kudzu to my nerdier friends as ‘a scripting language without the language,’ and that’s more or less accurate. Kudzu defines all of the stuff you’d expect a scripting language to have — class definitions, inheritance, properties, methods, and so forth — but does not define an actual syntax. Instead, Kudzu relies on scripting connectors, which translate Kudzu objects into a pre-existing scripting language.

Kudzu can use almost any existing scripting language. Currently, there are Perl and Javascript connectors, and they are both fully functional. I’ve taken a cursory enough glance at Python and Lua to see that it would be possible to connect them, but I haven’t begun that work yet. Any scripting language that can be embedded or extended will most likely work.

Kudzu applications are bundles. This idea is borrowed from OS X. Kudzu applications are directories which contain all of the templates, code, images, etc. needed to run the application, along with a small manifest file. Distributing the application is just a matter of compressing the directory and posting it somewhere. All of the runtime information is kept separate — preferences, db configuration information, that sort of thing.

Kudzu provides a rich data modeling environment. Similar to RoR’s ActiveRecord and Cocoa’s Core Data, Kudzu has a modeling environment in which you define the entities your application uses, and the properties of and relationships between entities, and Kudzu handles the fine details of how records are written to the database.

Kudzu handles all of the ‘overhead’ every web application needs to handle. The Kudzu core handles login / logout, session tracking, templates, form processing, cache control, and so forth. You retain the ability to muck with, for example, the outgoing headers, but it’s purely optional. In the simplest cases, all you have to worry about is your application’s actual logic.

Kudzu provides a rich cross-application ACL. If you’re running a Kudzu-based message board, and you add a Kudzu-based calendaring application to your server, all of the users of the message board can use the calendar without needing to create new accounts. You can assign members into groups and allow or deny them certain features in each application individually, but they’ll only need to log in to your website once to get access to all of the Kudzu applications you run.

Kudzu has a built-in plugin mechanism available for applications to use. So if you’re developing the Great Internet Web App, there is an existing, available, easy way for you to allow your users to develop extensions to your application. Plugins can extend the capabilities of an individual Kudzu application, or they can introduce new object types which are then made available for all Kudzu applications.

Those are the main things that make up Kudzu.

When you shake it, a lot of very neat things fall out of all of this. For example, if you’ve got an application written in Perl, and someone who only knows Javascript wants to write a plugin for your application, they can do it, and it will Just Work. (There’s a very slight speed hit in this case, because Kudzu has to translate back and forth between the two languages, but it’s actually minimal compared to, say, a database query.)

Since there’s a Javascript interface into Kudzu, you can write form validation scripts which can be executed on both the client and the server side. Just to be clear, the same code, not similar code — you only have to write the validation step once, and you get quick feedback for the client side and certainty on the server side.

When developing a Kudzu application, there are really only three things you need to worry about: the data model, the application logic, and the templates. The data model is simple, it looks something like this:

namespace Frobulator;
entity Widget {
  string name minlength(5) maxlength(50);
  number dingCount optional;
  relationship gummies entity(Gummy) toMany reverse(widget);
}
entity Gummy {
  binary flavor;
  relationship widget entity(Widget) reverse(gummies);
}

I’m hand-waving here, but that’s the gist of how you define a data model. Each one of the entity descriptions gets translated into a Kudzu class, and all of the glue code gets written for you so you can use them in your scripts natively. The actual database might be MySQL, SQLite, or some other database; you don’t have to worry about that when you design the model. The model gets translated into whatever bizarre dialect of SQL you choose when you install your app.

Right now SQLite and MySQL are supported and working, but this is easy to expand in the future.

The application logic is equally simple: you just provide a script-native object to use as a ‘delegate’ to the application, and define a series of methods on that object which correspond to the PATH_INFO required to get there. For example, if you’ll allow me to slip into Perl:

package Frobulator::Delegate;
use strict;
sub new { # not a method
  my $package = shift;
  return bless {}, $package;
}
sub Index { # handles / and /index
  my $self = shift;
  my $app = shift;
  return $app->error( 'Only the /about/frobulator page works.' );
}
sub About { # handles /about
  my $self = shift;
  my $app = shift;
  return $app->error( 'No, really, you must use /about/frobulator instead.' );
}
sub About_Frobulator { # handles /about/frobulator
  my $self = shift;
  my $app = shift;
  return $app->error( 'Just kidding, this is broken too.' );
}
1;

That’s a complete (if somewhat useless) Kudzu application. The function names represent the PATH_INFO by breaking them apart at the slashes, camel-casing individual words, and mashing them back together with underscores, so for example:

/about/frobulator/more becomes About_Frobulator_Mode
/console/to-do-list becomes Console_ToDoList

There’s a back-off routine which tries to call methods in sequence, so if you have a PATH_INFO of /really/long/path/info/string, Kudzu will try to call the following methods:

Really_Long_Path_Info_String
Really_Long_Path_Info
Really_Long_Path
Really_Long
Really
Index
(throws an error)

Anyway, the application above can be written in Javascript instead:

function FrobulatorDelegate() {
}
FrobulatorDelegate.prototype.Index = function( app ) {
  return app.error( 'Only the /about/frobulator page works.' );
}
FrobulatorDelegate.prototype.About = function( app ) { 
  return app.error( 'No, really, you must use /about/frobulator instead.' );
}
FrobulatorDelegate.prototype.About_Frobulator = function( app ) {
  return app.error( 'Just kidding, this is broken too.' );
}

As far as templates are concerned, there’s only one working template engine Kudzu uses right now, but the plan is to make it extensible in the future, to support ClearSilver, or Smarty, or whatever. The syntax is pretty simple, an extension of the engine I wrote for Diary-X, and pretty similar to every other templating engine on the planet. It handles compound variables, has basic control flow (if/else, foreach, while), function calls, server-side includes, and so on.

In all, the development is about 20% complete. I’ve got Perl and Javascript working together — Kudzu is actually bootstrapped in Perl at the moment, with about 6-8 Kudzu classes actually implemented in Perl instead of C. I have DB connectors for MySQL and SQLite both working (at least, they were working). I don’t have the template system ported into Kudzu yet, and I have to clean up the Entity / Model stuff a little before it’s functional.

You can still write a basic test application to prove the principles, though. See Cleanenger, compared to the Javascript-based source. Also look at /about and /about/cleanenger for the full effect. The application object is a bootstrapped Perl object, and its implementation is woefully incomplete, but the error method works.

So, to summarize:

  • Kudzu is a new, unreleased web application framework.
  • Kudzu provides an MVC framework in which each part can be chosen by either the developer or the user.
  • Kudzu allows multiple applications to seamlessly integrate with each other, so that users can be logged in to all of their applications simultaneously.
  • Kudzu handles most of the low-level details so that you don’t have to.
  • Kudzu allows plugins written in one language to communicate seamlessly with applications written in another language.

The question of the day: is this marketable? I don’t mean in the monetary, ‘can I make a buck off of this’ sort of way; I mean: if this was fully developed, would anyone use it? Is there a place for it somewhere in the long tail?

Today's Crazy Idea

Take one Connex 400XM-BT miniature computer from Gumstix ($169), paired with the breakout-gs ($28) and cfstix ($25) expansion boards. Sit a 6GB microdrive ($128) into the CF slot. Grab a GM862 cellular module from SparkFun ($146), and a F-51851 from Optrex via DigiKey ($77).

Result: one ugly-ass hand-built cell phone, for only $573!

Note to Michelle: this is not a Nintendo.