The only thing wrong with GoF Design Patterns is …

Jeff Attwood recently pointed out the difference between Gamma et al’s Design Patterns and Alexanders’ equivalent and outlined a critique of the former which characterises it as “replacing actual thought and insight with a plodding, mindless, cut-and-paste code generation template mentality”.

First, I want to note that the critique above surely defies belief to anyone who has used the patterns in practice. Patterns like the GoF design patterns are grammar for software architecture. If you search the technorati archives from when grammar emerged many millennia ago, you will probably find one or two bloggers was bemoaning the loss of creativity that this concept of sentence structure will cause. Fortunately, sense prevailed and now writers can be creative about the things that matter and not have to micromanage those that don’t. The progression of any discipline involves a cycle experimentation followed by optimisation followed by explicit statements of best practice (patterns), spiralling upward in level of abstraction. If I was so inclined, I’d go make a T-Shirt on CafePress that says “Patterns Take You Higher” with a picture of Bob Marley refactoring to Template Method.

So the GoF patterns are perfectly choice by me. The main problem with them is not the content per se, but the fact that most software developers think that pattern==GoF pattern and pattern language==the 23 patterns by Gamma et al. (1995).. If there’s ever a sequel, it would double the number of patterns in the universe according to these folks! In fact, there are thousands and thousands of documented design patterns out there, in the realm of software alone. (Admittedly, the most popular realm for design patterns, though there are still plenty of patterns for other disciplines too.)

This perception is silly.

Why do software patterns != GoF patterns? We can expand out from the GoF patterns in several dimensions (even staying within the realm of software):

  • Architectural Paradigm Even with patterns of high-level software structure, like GoF, we can model different architectural paradigms. GoF is all about general-purpose OO architecture; if you wanted to work with functional or logical languages such as Haskall or Prolog, you would need different kinds of patterns.
  • Application Type GoF patterns apply to the general structure of any medium+ scale architecture. There is still a wealth of advice to be gained from studying existing applications of the same type as you’re working on. This could be web server design, in-browser script design (like some of the Ajax patterns), mobile phone design, etc. For instance, the various J2EE patterns around, which were probably the second best known category of patterns in the industry (trailing GoF by a long margin though).
  • Perspective People see software from different perspectives; GoF patterns see it from that of a technical architect working close to the ground. You can also see patterns from the perspective of a user experience designer (usability patterns), project manager (software development process patterns), business analyst (business process patterns), programmer (coding idioms), etc. In this paper, we explained how patterns for usability alone could have all sorts of representations.
  • Domain The GoF patterns apply whether you’re working in banking, gaming, or web design. But each of those fields have their own idiosyncracies and fortunately there are pattern languages which capture them.
  • Opinion Even if you aim for the same problem space as Gamma and colleagues looked at, you will have your own views on the correct solutions. Patterns are opinionated, not objective, so your patterns will differ from theirs. As time goes on, any static set of patterns will naturally become less valid – it’s a testimony to Gamma et al that the patterns remain so very useful 12 years on (that’s a 256-fold increase in processing power according to Moore’s Law, and industry transition from C++ through Java and .Net through to Javascript, Ruby, and Python). Still, they’re not perfect; Singleton anyone?

One of the reasons the Gamma patterns are so successful is the fact that they apply so universally. However, this also leaves room for other patterns to come in and provide more specialised support.

Ajax Patterns has certainly been subject to this misconception; one review liked the content but prefers not to see it as a real pattern book – “Anybody who has read a real design pattern book and then read this book will soon feel the artificiality. ” Another refers to Gamma et al as “I read the original ‘Design Patterns’ book” and states “Those that read the original book will understand that packaging these topics as design patterns is insulting to those that know the value of actual design patterns. “. After many years of explaining usability patterns, I had anticipated these concerns with an appendix explaining the difference, but moreover explaining that it’s the content that matters most. There is also a perception that “Patterns” in the title sells more copies; all I can say is “I wish” as that buzzword went out the window around 2002. It’s called “Ajax Design Patterns” because they are, well, Ajax Design Patterns.

Bill Sanders gets it and recently discussed this phenomenon:

Buried in Appendix C (pg 605), Mahemoff distinguishes his use of design patterns from that of GoF, but it is not the kind of place that most developers are going to look when they pick up a book about Design Patterns. Likewise, Mahemoff uses the inside front and back covers to list the Ajax design patterns. On the one hand, anyone who reads those pattern names is going to know that this book is not about the kinds of design patterns GoF examine. On the other hand, the fact that the patterns are listed there, just like the GoF book, is a sincere form of flattery in the form of imitation.

Bill makes a good point about the Appendix C content being buried. Actually, relating the second point back to the first, I had in mind the similar statement by Gamma et al about Alexander’s patterns and their relevance, which also appears at the end. Still, in a pattern book, I’m not sure where to put something meta that won’t be buried; I’m sure the preface and intro are read about as much as the appendices. And I’ve certainly discussed the issue online before.

As for the covers, I liked the idea from GoF as well as Fowler’s UML Distilled book, and was particularly insistent on this because O’Reilly couldn’t do page cross-referencing.

Mahemoff is quite right in noting that the “original” design pattern book is Christopher Alexander et al’s town planning and architecture patterns book from the 1970s.(In fact in the Foreword to GoF’s DP book, Grady Booch mentions Christopher Alexander’s work.) However, common usage of design patterns in the context of computer programming has come to mean the kinds of patterns GoF talks about. Head First Design Patterns is a good example. No one was disappointed because they were surprised by the meaning of design patterns. Common usages in a given context come to have a specific meaning. In the world of quilt-making, design patterns mean something entirely different than in programming, and so no one is surprised when they get a book called Quilt Design Patterns and find out that there’s nothing about the Creational, Structural, Behavioral Design Patterns. However, in the world of programming, that is exactly what can (and did) happen in the case of Ajax Design Patterns, despite the fact that no less than Ralph Johnson reviewed parts of it.

(Emphasis mine) Yep, if you published a book of music patterns, there’d be no confusion. Still, I think our industry misses out because of this confusion. In an ideal world, there would have been 2 or 3 equally big hits at the same time, to get people’s mind around the fact that patterns are everywhere, not confined to the one (albeit excellent) text (I was going to call it “bible” but the one time I met John Vlissides, he told me he didn’t like it when his colleagues called it that :)). As it is, there’s the big ‘un, a few prominent others – typically in similar “high-level architecture” style to that one (e.g. the J2EE books, the POSA series and some of Fowler’s work), a bunch of books which used “pattern” for the hype value, and thousands of other books and one-time papers and blog entries. At one stage, Ward Cunningham was going to work with Microsoft to build PatternShare, a kind of meta-repo for all things pattern, which may have changed things, but apparently it never happened and the site is now down.

Quite apart from the book’s title, Mahemoff, does take up the invitation to contribute to design patterns offered up by GoF and he documents a number found in Ajax. While on a different level and with a different specific meaning than that found in GoF book, Mahemoff provides a wider view of design patterns and has what may be the best Ajax book on the market. It would be a shame if his work is diminished by the title, but among some, especially on the higher end, that may happen. Fortunately, the bulk of the reviews are readers who were looking for a good Ajax book and got exactly what they wanted.

This is where things get even more confusing, because the Ajax patterns (as with just about any other form of software pattern) actually relate to he GoF patterns. They’re different, but not entirely orthogonal. For instance, the daddy of all UI patterns, Observer, is present in patterns such as Virtual Workspace. My attitude is that patterns are there to be referenced and so I will happily reference other patterns from other languages if need be. In my mind, it’s all one big network of patterns (a PatternShare wiki, if you will).

Rails JSON, JSON Rails


p style=”clear:both; margin-top: 2em; “> Man, JSON has come out of nowhere! I first came across it amid the Javascript hype in early ’05, now it’s everywhere. Not only in your Ajax apps, but in the On-Demand Javascript APIs of the world.

Sharing an ethic of simplicity with Rails, it’s not surprising these technologies have come closely together, with JSON support now baked into the Rails core. (They would have been even closer together, if only anyone had noticed JSON==YAML early on and merged the two completely.) And yet, the current implementation misses a couple of tricks.

  • Use of “attributes”. According to Rails, a JSON object generally has just a single key, “attributes”. Instead of the simple { :name=>”Pac-Man”, :creator=>”Namco” }, we get (and have to give) { :attributes => { :name=>”Pac-Man”, :creator=>”Namco” }}. That’s not DRY. Not that it matters, but the reason for this is because ActiveRecords internally store persistable data fields in a hashmap called “attributes”. The JSON serialization is therefore faithful to Rails’ internal implementation, while being unfaithful to intuition. Maybe you could argue for “attributes” on the basis that you might one day have a transient attribute with the same name as a persistent attribute, in which case you’d get a clash. But Convention Over Configuration rules this argument out; you can always override JSON serialization behavior in boundary situations.
  • Child attributes This is probably an issue with XML as well. Basically, there is no attention paid to child attributes, i.e. JSON/XML serialization of a HABTM or has_many relationship. You want something like { :name=>”Pac-Man”, :creator=>”Namco”, :high_scores=>[{ :player_id=>1, :score=>99999 }, {:player_id=>2, :score=>88888 }] }, but all you get is the top-level attributes :name and :creator.

What to do?

First, I just discovered this extremely helpful library – Jsonifier, which also ships as a Rails plugin. It deals with both of the above problems. There’s no “attributes” chaff and it deals with associated records, even going recursive and letting you navigate from end of a many-to-many into the other. (In my example, you could show the names and ages of Pac-Man high scorers.) You also get to whitelist or blacklist attributes matches Rails’ associations syntax, i.e. :only, :except. Highly recommended, check it out.

Jsonifier, however, is pure to_json – it doesn’t (yet) handle deserialization. To my knowledge, there’s no Rails library that persists both parent and children in one go. There are lots of forum posts about handling multiple checkboxes and the like, and the answer usually involves overriding “children=” or “child_ids=”. I want to do this automatically!

I’ve been working out how to extend ActiveRecord to persist automatigically. I have the following very rough code working in basic situations, although it would need to do some more validation to work in production, among other things. It works on data structures such as the recurisve one above. You must first use a before_filter to convert the incoming JSON string into a Rails structure.

class << ActiveRecord::Base

def recursive_create(params) transaction do collections_by_children = pluck_hash_collections_by_children params new_model = self.create(params) populate_children new_model, collections_by_children new_model end end

def pluck_hash_collections_by_children(params) hash_collections_by_children = params.each_pair { |name, value| if value.class==Array hash_collections_by_children[name] = value params.delete(name) end } hash_collections_by_children end

def populate_children(new_model, hash_collections_by_children) hash_collections_by_children.each_pair { |children_name, hash_collection| new_model.send(“#{children_name}”).destroy_all child_class_name = children_name.singularize.camelize child_class = Object.const_get(child_class_name) hash_collection.each { |child_hash| child = child_class.create(child_hash) new_model.send(“#{children_name}”) << child } } end


module ActiveRecord class Base

def recursive_update_attributes(params)
  transaction do
    collections_by_children = self.class.pluck_hash_collections_by_children params
    self.class.populate_children self, collections_by_children


end [/ruby]

If HTML Used Convention Over Configuration …

Browsers would automatically pull in CSS and JS according to the filename and I would no longer have to look for an example every time I need a link or script tag.

In the absence of any other spec, /abc/def.html would cause the browser to look for /abc/def.css and /abc/site.css and /site.css. And then it would look for the same, but in JS – /abc/def.js, /abc/site.js, and /site.js. If I had all the time in the world, I’d make an Apache filter to do just that.

This would slow things down a little, but have you noticed – the world is becoming faster? It’s an another example of abundance thinking. Also, if it was a standard, it would not really slow things down as browsers and servers would develop protocols for speeding things up.

So I created a little Ajax web app template to put all the skeleton Ajax code on one page.


     <title>Hello World!</title>

 &lt;script type=&quot;text/javascript&quot; src=&quot;app.js&quot;&gt;&lt;/script&gt;
 &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;app.css&quot;/&gt;

</head> <body> <h1>Hello World!</h1> <input id="search" name="search" />

</body> </html>


body { background-color: white; }
div.error { font-color: red; }

search { width: 200px; }


function $(id) { return document.getElementById(id); }

window.onload = function() { $("search").onclick = function() { alert("The search begins!"); } }

New Website: Web-O-Random

I made a new Ajax toy. Web-O-Random is a random website finder with some Ajaxy goodness:

  • Sites load into a carousel (slider) component. Thanks to Bill Scott and Yahoo! for providing the original component and Sebastien Gruhier for the prototype port which is used here.
  • Pages load into an IFrame (as with WebWait).
  • User can re-randomize, which leads to a JSON payload of new random sites.

If you hunt for it, you’ll find there’s a way to search too, but I had to de-emphasise it as mysql full-text search takes 1-2 minutes to crunch through 4M (indexed) rows (each representing a website). If I have time, I may set up a reverse index table to cache results.

Initial reactions:

  • “…?” This is the typical reaction. It may be interpreted as a polite version of Cartman’s “Dude, this is pretty **** right here?” as in “Who would ever use this?”. Sometimes people forget that not everything has to be as popular as Google…apps like Weborandom and Webwait can be coded in a few days and hosting costs are pretty trivial nowadays. As development time trends downwards to zero, it’s the long tail of web apps! See What Happens When t Approaches Zero?
  • “So I get a new site by clicking Randomize?” (You’re meant to use the carousel first. I added some initial animation to the carousel, which looks cool and shows people there’s more than meets the eye. I also made the carousel default to start in the middle instead of on the left.)
  • “Are those your ads?” (He thought the carousel was adsense. I refactored by showing a boldfaced website title instead of a blue link).
  • “How do I click the arrow key? I can’t see the cursor.” (Confusing to have keyboard bindings in the absence of a textarea/input control. Changed the instruction text.)

Linux Journal Editor’s Choice Award, Development Book – Ajax Design Patterns


Just discovered Ajax Design Patterns has received the 2006 Editor’s Choice Award from Linux Journal for books on software development. It’s a personal honour, but it’s also a sign of the groundbreaking role Ajax has played in 2006.

Ajax Design Patterns, published by O’Reilly, assumes that you have a good idea of how HTTP, HTML, the DOM and CSS work (although it does help you brush up as necessary), and it shows you how to combine the basics into sophisticated applications. You can almost think of it as an Ajax cookbook, but with the underlying theory and advice that you need to make interesting applications.

Thanks to Jason Salas for passing on the news (Jason followed the book’s progress as it evolved and recently wrote a positive review on his blog.)

Ajax Diagnosis And Testing Patterns – Podcast

Welcome to Ye Olde Ajax Patterns Podcaste, the final in this series that began twelve months ago. 3+4+4+1 = 12 podcasts in all, covering 71 patterns (the 70 patterns in the the book as well as Dyanmic Favicons). Find them all on the podcast category – or subscribe to the podcast feed at Thanks for listening!

This podcast covers eight patterns on debugging/diagnosis of Ajax Apps, as well as testing Ajax apps, and I’m joined by Craig Shoemaker from Polymorphic Podcast, also a co-author of “Beginning Ajax with ASP.NET”. After some announcements, the interview begans at 6:00. The podcast overall is 60 minutes.


p> Ajax Diagnosis Patterns:


p> Ajax Testing Patterns:

With the series now complete, the podcast will now resume regular Sotware As She’s Developed topics including but not limited to agile development, Ajax, the web, and usability. Also, more conversations – please drop me a line at [email protected] if you’d like to come drop in for a skype chat.

As always, credits on this podcast to My Morning Jacket for the lead-in track, “One Big Holiday”. All podcasts in this series licensed under CC.

Audio Note: Sorry about the noise at some stages in this recording – I now know a lot more about audio levelling (the problem of keeping both ends at the same level), but at the time this was recording, it turned out I had set Craig’s end at too low a volume. I used Levelator to level each end, leading to too much noise…next time I’ll need to pump up the volume at each end from the start. I’m also looking forward to resuming use of Bias SoundSoap, but there’s no easy way to get this running on an Intel Mac for now!

Ajax/Javascript: 8 Ways to Create Graphics on the Fly

<a href=''>Ajax/Javascript: 8 Ways to Create Graphics on the Fly &#8211; digg this</a>

The ability to create rich graphics on the fly is one of the critical gaps in Ajax. There are indeed techniques to do it, albeit far from perfect, and some are do-able today if you take a pragmatic view of things and keep graceful degradation in mind.

Here I list all the techniques I can think of to create graphics and images dynamically when you’re creating an Ajax/DHTML/Javascript web app, with varying degrees of portability and usability. Starting with the obvious and ending with the obscure. Please submit any other techniques you’re aware of!!!

  1. Use SVG. Current versions of Firefox, Opera, and Safari (nightly builds) support SVG natively, but with IE and older versions, users need to install a plugin. SVG is an old W3C standard that creates images based on XML. Being a vector format, it stores the image at a high level (curves, lines, etc), so it scales better than a plain bitmap. Here’s an SVG circle (adapted from W3CSchools:

    1. <svg width="100%" height="100%" version="1.1"
    2. xmlns="">
    3. <circle cx="25" cy="25" r="30" stroke="black"
    4. stroke-width="2" fill="green"/>
    5. </svg>

    You could build up the XML string in the code or pull it down from the server with a remote request. However, you don’t actually have to specify the XML as a literal string message; you can create a blank SVG document object model (DOM) and manipulate it to build up an image. In this example, we create a circle of radius 25 (adapted from this tutorial):


    1. var svgDocument =;
    2. var shape = svgDocument.createElementNS(svgns, "circle");
    3. shape.setAttributeNS(null, "cx", 25);
    4. shape.setAttributeNS(null, "cy", 25);
    5. shape.setAttributeNS(null, "r",  20);
    6. shape.setAttributeNS(null, "fill", "green");
  2. Use Canvas. Canvas was introduced in Safari and now in Firefox and Opera too. No sign of life in IE, but this there’s a fantastic adaptor hack (via Ajaxian) that emulates Canvas using IE’s native VML support (more on VML below), and it’s now been rolled into an open-source project, ExplorerCanvas by some Googlers.

    Where SVG is about things, Canvas is about actions. SVG documents represent images. Canvas tags include code to build up an image, a bit like moving a turtle in the Logo language. So you set a colour, draw something, change the fill style, draw something else, etc. You manipulate a Canvas tag like this:


    1. var canvas = document.getElementById('tutorial');
    2.   if (canvas.getContext){
    3.     var ctx = canvas.getContext('2d');
    4.     ctx.fillRect(25,25,100,100);
    5.     ctx.clearRect(45,45,60,60);
    6.     ctx.strokeRect(50,50,50,50);
    7.   }

    (BTW Canvas uses the dreaded term, “Context”, to refer to what should really be called “paintbrush”, “pen”, or “turtle” … more concrete terms than “Context” which imply some sort of metaphor. But wouldn’t an imperfect metaphor be easier to grok than the generic “Context”? Alas, it’s a common idiom in graphics programming and will be around for a while.)

  3. Load dynamic images from the server. Once you have an image tag (either in the initial HTML or created on the fly with document.createElement(“img”), you can set its source to any URL, even external to your domain (though cross-domain “hot-linking” should generally be done only with permission). This is standard DHTML/Ajax stuff and works with any browser.

    1. button = document.createElement("img");
    2. button.src = ""
    On the server, the image need not be a static image file. It can be a server-side script that happens to output a binary image with the appropriate header, and furthermore, the script can accept CGI parameters, so a unique image can be generated on the fly. Of course, performance will probably suffer if you rely on the server to create images on the fly, and you can only generate them once a second or so. The various Ajax image manipulation tools do something like this.
  4. Use Vector Markup Language (VML). VML is effectively the MS equivalent of SVG, and as such works in IE, and only in IE. As with SVG, you use XML to specify an image.
    1. <v:oval style="position:absolute; left:0; top:0;
    2.               width:100pt; height:50pt"
    3.               fillcolor="red">
    4. </v:oval>
    Fortunately, the Canvas-on-VML hack mentioned earlier means you can take advantage of VML without committing to IE-specific code, though it’s (obviously) not a perfect emulation by any means.
  5. Introduce a Richer Plugin, most likely Flash, to beef up the browser’s multimedia capabilities.
  6. Rely on plain old CSS and the DOM. You can do some impressive-looking things with just CSS and the DOM, e.g. the CSS graphs library. And of course it’s easy enough to make it fully portable too.
  7. Create an image and set its src to a data: resource. Firefox and Opera only. From Dive Into GM:

    1. var logo = document.createElement('img');
    2. logo.src = 'data:image/gif;base64,R0lGODlhDQAOAJEAANno6wBmZgAAAAAAACH5BAAAAAAA'+    'LAAAAAANAA4AQAIjjI8Iyw3GhACSQecutsFV3nzgNi7SVEbo06lZa66LRib2UQAAOw%3D%3D';
    3. document.body.insertBefore(logo, document.body.firstChild);
  8. Embed an XBM file. Yes, some browsers can display XBM images. Works on IE and Firefox, but not Safari or Opera. Unfortunately, XBM has the rather major constraint that it’s black-and-white. However, it does have the virtue of being a plain-text format which, like the data: protocol, you can assign an image source to.

    If you get your image data in that format in a string (complete with the n after each of the #define lines), then you can make any image’s SRC attribute be:

    XBM’s not used often, but there are some nice examples: Wolfenstein 5K, most notably, as well as this bitmap editor and a sparklines library.

(Off-topic: I’ve just updated my blog page, I prefer the 2-column sidebar because: (a) there are now 20 monthly archives links; (b) I wanted to add a ton of chicklets; (c) I wanted to add more bio info. BTW If you have a blog, here’s a quick exercise: Place yourself in the mind of a new visitor for twenty seconds, and decide if this person could work out who you are, what you do, and how to contact you. Around 90% of blogs fail this test on the grounds it’s impossible or way too hard.)

Lessons in Javascript Performance Optimisation: 90 seconds down to 3 seconds

Summary: Avoid $$(“.classname”) on large DOMs!!!

I’ve recently been optimising the guts out of a JS webapp I wrote, which was making IE crawl to a halt. I discovered this after introducing a stress-inducing data set. (Using Rails’ fixtures makes light work of this; since the fixtures are Ruby templates just like the web templates, it’s easy to introduce a loop to create lots of data.)

With a rather large data set (100+ items, each several fields), IE would take about 90 seconds to churn through the initial script before the user could do anything. Firefox would run the same thing in about 8 seconds, still too long for a web page, but incredibly about ten times as fast as IE. I’m wanting to avoid pagination at this stage, so first priority was to tweak performance and see if we can keep everything on the same page.

After some sophisticated profiling ((new Date()).getTime():D), the main culprit was revealed to be prototype’s $$. It’s a fantastic function, but if you try to grab all elements belonging to a certain class, and the DOM is really big, $$(“.cssClassName”) can be slow. REALLY SLOW in IE. Remedy:

  • Removed trivial usages of $$() – e.g. in one case, the script was using it as a simple shorthand for a couple of DOM elements, and it was easy enough to hardcode the array. i.e. $$(".instruction") becomes [$(“initialInstruction”), $(“finalInstruction”)]. The former notation is cuter, but unfortunately impractical on a large web page.
  • Introduced the unofficial selector addon. Seems to have improved performance in more complex queries, i.e. $(“#knownId .message”), but doesn’t seem to have affected performance of $$(“.classname”).
  • Finally, I bit the bullet and scrapped $$(“.classname”) altogether. It’s more work, but the script now maintains the list of elements manually. Whenever an element is added or removed, the array must be adjusted. Furthermore, even the initialisation avoids using $$(), thanks to some server-side generated JS that explicitly declares the initial list of elements belonging to the class (i.e. the list that would normally be returned by $$()). To do this, the following function is called from onload(), generated with RHTML.


  1. function findAllItems() {
  2. <% js_array = { |item| "document.getElementById('item#{}'),"}.join
  3.       js_array = js_array[0..-2] if @items.length>0 # Drop extra comma at end -%>
  4.       return [<%= js_array %>];
  5. }

The last step explicitly identifies all items in the class, removing the need to discover them by traversing the DOM. I wasn’t really sure how much time it would save – after all, you still have to look the elements up in the DOM and assign them to the array. But when I tried it, the savings were supreme – on IE, from around 45 seconds to about 2 seconds.

I have also incorporated Dean Edwards’ superb onload replacement to get the ball rolling before images are loaded. It’s a neat trick and takes 5 minutes to refactor it in.

Ajax Functionality and Usability Patterns – Podcast 4 of 4: Functionality Patterns

This is the fourth and final podcast in the series on Ajax functionality and usability patterns (Book: Part 4, pp 327-530). This 54-minute podcast covers seven patterns of Ajax Architecture (Book: Chapter 17, pp 473-530):

Dedicated to the Nitobians, whose last podcast inspired me to crank another one out again. Recent events suggest it may cost me $5000 to appear on their podcast again, and as Andre points out in this podcast, the same applies for them appearing on my podcast. Thus, my simple proposal would be:

  1. Each of us appear on the others’ podcast, at $5000 each. Actually, let’s make that $50k each.
  2. Cancel the debt
  3. Now each of us can claim our podcast attracts guests who pay $50k to appear. Enough to cover headsets ($20), bandwidth ($10/month with Libsyn), and assorted beverages (name your price).
  4. Profit!!!

Soon I’ll be publishing the final podcast in the overall series, which has already been recorded, and then I’ll be taking it in a more general direction akin to the topics on this blog – talking about agile, programming (Java/Rails/etc), usability, Web2.0, as well as Ajax and the coming revolution of real-time webapps. If you have a skype account and you’d like to join me sometime, drop us an email ([email protected]). Also feel free to suggest any topics that would be good to cover.