Sunday 27 December 2009

Boston Roundup

First off, just to get this out of the way, Hyatt Regency Boston: nice enough hotel but 50c/min for internet? They do realize that works out to $30/hr right?! I mean... heck, I'm speechless. And I can't decide which is worse, that or the $36/day for parking. Luckily I didn't have a car.
From Boston '09 (Steven Noble)
I was in Boston a few weeks ago to take Product Management training (happy to report I passed the certification!). An old friend of mine came down from Ontario and we took in the town for the weekend. We spent much of Saturday wandering around Cambridge and then walked the Freedom Trail back through the North End, Boston's fabulous Little Italy.
The financial district had a nice sense of scale, not unlike downtown Vancouver (if you ignore the West End) or maybe... Perth? And Boston Commons is a perfect feature in the heart of downtown; it's nowhere near the size of, say, Central Park or Stanley Park but is one of the nicest city parks I've seen.
Overall, I liked the feel of Boston, and the snow and drizzle failed to dampen our spirits. I have to confess that I found Cambridge pretty uninspiring, though. I expected Harvard and MIT to exude a sense of history and achievement—like the colleges in Cambridge, England or even Trinity College in downtown Dublin—but they felt like little more than a collection of oldish buildings. Maybe the preponderance of brick as a building material simply fails to impress.
On Sunday night, I went for dinner with Carl Gundel and Chris Norton, two Boston-area one-time Squeakers. As in Vienna, I presented a convenient excuse for Smalltalkers who hadn't crossed paths in years to get together. We had some interesting discussions and hopefully reignited the Smalltalk spark in Chris.
Kudos to Yelp for the recommendation of Bar Lola and to Zagat for the pointer to delicious Italian food and friendly service at Carmen. Oh, and I loved the Equal Exchange Cafe — wish it was in Vancouver.
As usual, click any of the photos above to see the others I posted. Or check out Steven's photos from the trip.

Wednesday 16 December 2009

Training in Boston

So I'm most of the way through this jaunt down the US East Coast and have yet to post even a single update (unless you count the occasional tweet). I know, I know... what can I say? I've been busy. My first attempt was overly rambling so I'm going to focus on one aspect here and follow up with a few more posts over the next couple of weeks.

The main reason for the trip was a Product Management seminar led by Steve Johnson of Pragmatic Marketing—and I definitely recommend the course to anyone who's interested in this stuff. One thing I found interesting: in North America smalltalk usually means asking, "so what do you do?"; well at a seminar made up of 30 people who all do the same thing, that gets replaced with, "so where do you work?". Fun watching the puzzled looks on people's faces as they stared at the blank line below the name on this independent consultant's name tag. :)

The main focus of the course is on guiding product development through market problems and on grounding those problems in real data instead of hunches and "wouldn't it be cool if...?". I'm interested in Product Management from two angles: first, as a possible career direction and, second, in its applicability to open source projects, such as Seaside.

In past jobs, I've found myself naturally trying to fill an institutional void. I've been the one asking, "Are you sure the students want an on-campus version of Facebook? I kind of suspect they just want to use Facebook...". Actual demand for what we were doing, the exact problems we were trying to solve, and even the development costs have all been more-or-less-hand-wavy things. How do you know what to implement if you don't know what problem you're solving and for whom? Or, to look at it another way, if you develop without that knowledge, how do you know anyone will find the result valuable? It was revealing for me when I first learned there are people who make a living doing these things I found rewarding.

The applicability to open source is an interesting issue. On the one hand, it is almost intuitively obvious that most of the same factors apply. A project that meets a market need will succeed while one that does not will fail. A project that knows who its users are can be more effectively marketed; one that does not will succeed only through chance or an inefficient shotgun approach. What I'm not sure of yet is what is different: is it the formulas, the costs of the resources, or maybe their units of measurement? Or do we need to tweak one or more of the definitions? As a random example, Product Management makes a distinction between users and buyers of a product; what's the correct mapping for these concepts in open source? I'm still pondering all this... more to come.

Before I leave off, I should mention that the Hilton DoubleTree in Bedford is one of my best hotel experiences in recent memory. Everything was efficient and painless. The room was roomy, modern, and spotlessly clean. The internet was fast and free. And the (three!) extra pillows I tossed on the floor were left there neatly for my entire stay instead of being put back on the bed. They even insisted on comping a meal I had in the restaurant which was, admittedly, slow in arriving but not to the point I was concerned about it. So, I don't know why you'd be in suburban Boston, but if you are, go stay at the DoubleTree.

Wednesday 2 December 2009

New York presentation confirmed

The details for my talk in New York have been confirmed. We'll be at the Suite LLC offices (directions) on Thursday, December 10; there's an open house at 6:30pm and the presentation is at 7:00 (drinks afterwards).

Here's the planned subject of the talk, though I think I'll play it a bit by ear and see what people are interested in:
Seaside is a rare example of software that runs on all the major Smalltalk platforms: Pharo, Gemstone, GNU Smalltalk, Squeak, VA Smalltalk, and VisualWorks. We’ll take a look at some of the challenges in keeping the framework portable and some of the techniques the team has developed to deal with these. Along the way we may also touch on tools such as Grease, Slime, and Monticello and how they help the process. And then we’ll see where the discussion leads.

Friday 27 November 2009

Fresh Tracks!

Wow. After the snowiest month on record, what a beautiful day for Blackcomb's opening. Much of the mountain was ice after yesterday's rain but that first run down untouched powder in 7th Heaven made the whole trip worthwhile. And the second run. And the third (ok, no longer untouched by this point). I'd almost forgotten how beautiful snowboarding can be on a sunny day.

Tuesday 24 November 2009

Boston, NY, Raleigh

I've confirmed a December trip to the US East Coast. In Boston, I'm attending a product management seminar put on by Pragmatic Marketing, meeting up with a few Smalltalkers from the area, and planning to pop in on the Boston Ruby group's monthly meeting if I can squeeze it in.

On Thursday, December 10, it looks like I'll be giving a presentation at the NYC Smalltalk users group—Charles was kind enough to try to schedule something around my timetable. Details are not quite confirmed; I'll try to remember to post an update here but keep an eye on their site if you're interested. I'm planning to talk a bit about the techniques and tools we use to ensure Seaside portability across the various Smalltalk dialects but we'll see where the conversation wanders. I'm also planning to visit with friends, enjoy the pre-Christmas season in New York, and maybe do some shopping.

Finally, I'm making my way down to visit the VA Smalltalk team in Raleigh, North Carolina. John and I are planning to put our heads together on a couple of issues and I think I'll be doing a Seaside tutorial for some of the engineers while I'm there.

I'm looking forward to a productive, if exhausting, trip. Drop me a line if you're in one of these areas and want to meet up.

Friday 20 November 2009

SIXX port for VASt

I just published an initial port of SIXX to VAStGoodies. Most of the tests are passing and I'll push the minimal changes I made back upstream for integration. Just like the Pier and Magritte ports I recently finished, this one was requested and released back to the community by Nationaal Spaarfonds.

The plan is to see if I can use SIXX for Pier persistency... that'll be the next step.

Tuesday 3 November 2009

Pier for VASt

I mentioned a couple of weeks ago that I had uploaded an initial port of Magritte for VA Smalltalk. I've spent a couple of days since then (again courtesy of Nationaal Spaarfonds) getting the Pier port cleaned up and posted. Currently none of the add-ons have been uploaded but I have the security package mostly done and it will follow shortly.

Consider these alpha releases: they are being heavily updated to work with the newest Seaside (3.0a5 currently) and to sort out compatibility with different platforms. With that said, though, all of the Pier tests and all but four of the Magritte tests pass, so give them a try. You'll need the B130 development build of VA Smalltalk.

The original Pharo sources for these Seaside 3.0-compatible versions are available: pier repository magritte repository. Again, these packages are still in flux. They're now built on top of the same Grease portability layer as Seaside 3.0a5; I'd encourage interested platforms to give them a try and see how easily portable they are.

Monday 19 October 2009

Magritte for VASt

Over the past month or so I have been doing some work for National Spaarfonds, including porting Magritte to VA Smalltalk. They are generously offering this work back to the community and I am happy to announce that I have just uploaded the first version of the VASt Magritte port to VAStGoodies.

You'll want to start with the VASt 8.0.1 [128] developer preview image and then load the configuration map from VAStGoodies. There are currently four failing tests: three caused (I think) by method inlining and one by differences in error handling behaviour. I haven't yet determined what (if anything) can be done about these.

A version of Pier ported to Seaside 3.0 and VASt won't be far behind but I have some more cleanup to do first in order to make sure it loads into a clean image.

Friday 9 October 2009

Vienna or bust

I've been wanting to visit Vienna at least since my arrival in Germany last year —particularly after trying to learn the Viennese Waltz in my ballroom dancing class—but could never convince anyone to come along. Thanks largely to an invitation from Bernhard Pieber, I finally made the trip.
And I've been busy: as well as trying to take in Viennese culture and some of the sights, I also presented an introduction to Seaside at mobilkom austria and had the chance to meet some local Smalltalk and Seaside developers over dinner and beer. It seems to take the arrival of a foreigner to prompt the locals to get together (no surprise: the same is true in my home town!).
Vienna is much as I imagined: a real "European" city with beautiful old architecture everywhere you look. A visit to the Kunsthistorisches Museum would have been worth it just to see the building itself, but I was also struck by a couple of sculptures and by several paintings by Pieter Bruegel and Lucas I. van Valckenborch. It's interesting that I liked both artists since it turns out that van Valckenborch studied under Bruegel and Bruegel's Tower of Babel, which was displayed in the museum, was the model for van Valckenborch's version, which hangs in the Louvre.
First thing one morning, I walked to the Spanish Riding School to watch the exercises of the Lipizzaner Stallions. I thought Lipizzans were all grays but apparently that is simply the dominant and selected gene and it is tradition to keep at least one bay at the school at all times. The horses and their riders are impressively controlled and the Winter Riding School itself is astounding too: is there anywhere else in the world where you can ride a horse on a bed of sawdust, surrounded by two levels of marble balconies and lit by enormous chandeliers?

We saw a big band concert at a local jazz club and got standing-room tickets to a sold-out orchestral performance with Lang Lang (郎朗) on the piano and Zubin Mehta conducting. I would have gladly paid the extra for a seat if one was available, but these €6 standing tickets are a wonderful idea to make the symphony more accessible. The only disappointment was the sound in the concert hall, which seemed somewhat flat, probably due to our location under the balcony.

Schloss Schönbrunn (the former imperial palace) is also worth a visit. The expansive gardens are enjoyed in the mornings by walkers and runners and, despite the tourist hoards, the Gloriette perched on its hilltop behind the palace, creates a striking image. The palace museum was interesting too: among other things, I discovered that Marie Antoinette was Austrian (she, like most of her 10 sisters, were married to foreign royalty for political reasons).

Like I said, I've been busy.

Thursday 8 October 2009

Seaside 3.0a5

The fifth alpha release of Seaside 3.0 is out. Check out the release announcement. It's looking like Cincom, Instantiations, and GemStone will all include this version in their next upcoming releases; Pharo users can use the Seaside Builder to generate a load script. Squeak users will probably have success using the Builder as well, but we are looking for one or more people to actively test and maintain a Squeak port. Get in touch if you're interested.

We're expecting this to be the final alpha release, so now is the time to actually send in any bug reports you've been sitting on.

Sunday 4 October 2009

Languages - the other kind

A few days ago, Adriaan and I checked out Inglourious Basterds. It wasn't really what I was expecting (what was I expecting?) but it was well done overall and I enjoyed it. Christoph Waltz was the highlight for me: the cunning Col. Hans Landa was just plain interesting to watch. The movie kept me engaged right up until he finds the shoe (I'll leave it at that so as not to give anything away), at which point things seemed to go steeply downhill and the movie stopped feeling like it was going anywhere. It never really recovered.

The most rewarding part for me, though, was watching a movie with three spoken languages and understanding just about all of it. I was particularly keen to see the movie in the Netherlands where the absence of dubbing and my inability to read the subtitles left me free to take it in without distraction. Anyone know any other German/French/English movies that are worth seeing?

Monday 28 September 2009

Seaside at Amsterdam.rb

I'm just back from the monthly meeting of the Amsterdam Ruby User Group at De Bekeerde Suster in Amsterdam. The cheeseburger was delicious, though I was slightly offended when the guy who brought the food said, "Let me guess... you want ketchup?". It's not like I'd even said a word; how could he have decided I was north american? :)

We talked about their plans for the RubyEnRails conference coming up on October 30 and shared some of our experiences from ESUG conferences. There was quite a bit of discussion around how to encourage programmers to give lightning talks. I also took a few minutes to give an overview of Seaside. Everyone there was quite interested in Smalltalk and the level of awareness was already quite high. We had some interesting discussions of the language's history as well as its benefits and limitations. In the end that made up a good part of the evening.

Thanks for the warm welcome.

Monday 21 September 2009

In Bruges

I spent this weekend in Belgium. Arriving in Bruges after dark, I was greeted by the clip-clop of horse-drawn carts on cobbled streets (what an amazing sound!) and narrow lanes lined with medieval stone and brick buildings. The whole scene is gently lit by street lights that manage to avoid casting the gloomy sodium-light shadows found most places. Bruges by night is one of the most beautiful and romantic cities I have seen.
Incidentally, apparently I'm one of the few people left in the world who hasn't seen the movie In Bruges (oh it's recent... no wonder I didn't see it: I was in China), since it's all anybody talks about whenever Bruges comes up in conversation.
I had already decided to go for a run on Saturday when I looked at the online event listings and found there was an organized run happening and not much else that interested me. So, after a pleasant boat tour around the canals, I took my advice from last week one level further and saw the area around Bruges while running a 15km race.
For dinner, I found an excellent restaurant called De Vlaamsche Pot (The Flemish Pot), which serves local regional cuisine. The two-storey restaurant is cleverly laid out throughout a restored period house, complete with huge wooden beams in the ceilings. It is charmingly decorated and it successfully creates the atmosphere of somebody's dining room without any of the rooms feeling cramped at all. On top of that, the service was excellent in any language you can think of and the food was terrific. I filled up on delicious Flemish beef stew and didn't have room to even consider dessert.
The city's charm is tempered slightly during the day by the hoards of ambling tourists but not enough to put a damper on the weekend. It would be nice to do some day trips in the area some day: I'd love to see the fields of poppies and maybe check out Ypres and its Menin Gate, a painting of which struck me while in Canberra a number of years ago. It's always good to save something for the next visit.
Belgium brings my number of visited countries for the past three weeks to six and it looks like I'll hit at least seven before making it back to Canada... whew.

Friday 18 September 2009

Smalltalk on AppEngine

Torsten posted a link to the announcement of GwtSmalltalk, which compiles to JavaScript and runs on top Google Web Toolkit and, thus, AppEngine. This is interesting coming only weeks after Avi's announcement of Clamato... there's clearly some interest around combining Smalltalk and JavaScript at the moment.

You can try out a demo. Hint, to create new instances you need to use:

Kernel instanceOf:

Saturday 12 September 2009

On Walking

Whenever I find myself in a new city, I like to walk. I find a map; I pick a direction, a neighbourhood, or an arbitrary destination; I put on comfortable shoes, and I walk somewhat aimlessly, just taking in what I find. Often I'll do this for days in a row, each time in a new direction. The endpoint and the route are irrelevant because it's about the journey itself.

There seems to be no better way to get a true sense of a city. You're really missing out if you think that Paris is all about the Eiffel Tower, that Beijing is characterized by the Forbidden City, or that you'll get a full understanding of New York by riding the subway and visiting Times Square. Oh sure, make time for those landmarks if you want, but what's really interesting is a city's people, its architecture, back alleys, corner stores, sidewalks, graffiti, parks, and used bookshops.

In Beijing I walked for weeks—hours every day—trying to puzzle out hànzì characters and discovering hidden temples, noodle shops, and bicycle repair stands. Day after day, I remember being constantly astounded by the sheer quantity of life that is lived every day in that vast city, by the amount of observable change from week to week.

Wandering in central Berlin one day, I stumbled across a brick line in the road, marking the former path of the Berlin Wall. I traced this line from Brandenburg Gate, through quiet residential areas, alongside concrete walls covered with vibrant murals, past memorials, and down renovated green spaces. As I picked my way east towards Warschauer Straße across the river, I felt a real sense of the history and the difference, still visible, between west and east.

In Kolkata (Calcutta), on possibly the only occasion when "the children" (we were 26) were allowed to roam the bustling downtown streets freely by ourselves, we stumbled across a serene old church with a graveyard full of interesting 250-year-old tombstones. There we hid from the beggars and hawkers and attempted to decipher the epitaphs engraved in old-fashioned English script.

The last two days, I wandered Frankfurt. Yesterday I took in the riverside, with its grassy banks, apparently covered with runners once the work day ends. I wandered downtown, enjoying the modern low-rise office buildings and German-style half-timbered houses, the quiet cobbled squares and the wide-open bustling shopping street. Frankfurt is perhaps not the most noteworthy of cities but it has a comfortable scale and pleasant feeling of balance.

Today, wanting to go farther afield, I caught an S-Bahn out of town, thinking I'd look for the Cincom office, which I knew to be in that direction. Only 20 minutes out of downtown, I got off the train in South Kronberg and discovered apple orchards, corn fields, vistas of church towers and rolling hills, and people riding horses right past the business park! In a field beside the passing cyclists and trail-walkers, a middle-aged man practiced paragliding. Wandering south through Niederhöchstadt, I then lucked upon an Apple Festival and made lunch out of apple wine and bratwurst before catching a return train.

Each city has a rhythm and you won't find it sitting in your car, your hotel room, or the ticket queue for the tourist sight of the day. So get out and walk.

Monday 7 September 2009

ESUG 2009 wrapup

Well, as I recover from another busy but very fruitful ESUG, it's interesting to look at what made it such an enjoyable conference. There is a real sense of community there that makes it a pleasure to attend every year.

There were some interesting presentations but, for me anyway, the true value was in the networking and personal conversations. I made some interesting new contacts, renewed some old ones, and rounded up some consulting work that will keep me in Europe for a little bit longer. The organizers made some last minute changes this year to help encourage these sorts of meetings and I hope we will see more of this sort of thing next year.

My overall impression is that these are interesting times for the world of Smalltalk. There seems to be a sense of common purpose and renewed life at the moment and it's satisfying to think that Seaside has played at least a small role in making that happen. I'm not sure what lies ahead, but I think opportunities will arise that we need to take advantage of. I'm also not yet sure exactly what part I want to play but I'm starting to think seriously about it.

My tutorial with Lukas was well received. As usual, we didn't quite manage to get through all of our material, but it went pretty smoothly and I think the thirty-or-so participants all picked up some new tricks to use in their Seaside projects.

The Seaside sprint was very successful, even though we didn't quite meet our target of finishing a 3.0 beta release. Keep an eye out for an announcement when we do get it done.

I'll close with links to a few people's photos:
Hope to see you all next year in Barcelona!

Wednesday 2 September 2009

Seaside 3.0 and Documentation

For those who aren't at ESUG this year and missed Lukas' tweet, we announced yesterday that the Seaside 2.9 alpha series will become Seaside 3.0 when we go to beta.

We feel the name is well earned: a cleaner architecture, increased flexibility, better documentation, improved portability, and jQuery support make Seaside 3.0 an even more solid base for developing powerful web applications. They also lead the way for more incremental changes in the future and should make life easier for anybody who wants to develop tools or other frameworks on top of Seaside.

We will be running a Seaside Sprint here in Brest from Friday afternoon through Saturday and the goal is to get the remaining issues resolved for a first beta release. Please join us if you have the opportunity.

Also announced at ESUG, was the release of the online book Dynamic Web Development with Seaside. It's a great resource: make sure to check it out and contribute comments and content.

Saturday 29 August 2009

ESUG and Keychain integration for Firefox

I arrived this afternoon in Brest, France for the ESUG 2009 conference. I didn't write much Smalltalk but got caught up with a few people and had a couple of interesting discussions.

There will be much Seaside to come but, taking a break from that over the past few days, I also managed to get a beta version released of my Keychain Services Integration extension for Firefox that allows OS X users to store their logins and passwords in Apple's keychain. This allows the passwords to be shared with other browsers like Safari and Camino and also lets you take advantage of features like Keychain locking to protect your stored passwords. If you use Firefox 3.x on OS X, give it a try and let me know how it goes - it's scratching an itch for me anyway.

Tuesday 14 July 2009

Through the eyes of a child

On a whim, while walking in London yesterday, I popped into the Tate Modern gallery. I'm not a huge modern art fan, but a few pieces caught my attention. Two of the most interesting were No Title (Table and Four Chairs) and Red Room, which I've just discovered are both by Robert Therrien.

Red Room is, as the title suggests, a room where every single object (except the single white light bulb in the ceiling) is practically the same shade of red. The room is packed with stuff and it's surprisingly compelling to look at. The collection of objects screams that there's some hidden story here waiting to be deciphered.

No Title (Table and Four Chairs) is a large scale (3.5 times normal) dining table and four chairs. On first glance, I thought, "ok, a big table". But the more I studied it, the more I was almost unable to walk out of the room. I began to contemplate the effect of looking up at the underside of a table, of standing barely higher than the seat of a chair. Obviously, as children, we all saw the world from exactly this position, but I found the situation almost impossible to fathom, let alone to recall. Very interesting.

Check out photos of both or if you're in London drop by the gallery and see them for yourself.

Monday 29 June 2009

Web Velocity released

Big news from Cincom on the Seaside mailing list today: they've made an evaluation version of their commercial Seaside-based Web Velocity environment available for download. In case you've missed the buzz, Web Velocity takes Seaside running in VisualWorks Smalltalk, adds ActiveRecord integration and a web-based development environment (written in Seaside, of course). If you're curious, head over and download a copy.

Tuesday 23 June 2009


I'll be in London (UK) on Wednesday June 24 for 10 days or so. If anyone around there wants to meet up for a beer and talk Seaside, Smalltalk, or something else, send me an email or add a comment. Or if there are any good tech meetups during that time I'd be happy for a pointer.

Friday 5 June 2009

Seaside 2.9 on VisualWorks

Good news from Cincom: it seems they have Seaside 2.9 ported to VisualWorks with all tests passing. They didn't start very long ago and I haven't heard the sounds of much struggling coming from that direction so it seems like porting wasn't too difficult. I'll give myself and the rest of the development team a pat on the back for that one!

Meanwhile, we're eyeing another alpha release and trying to stare down a few remaining rough edges that are preventing a reasonable attempt at a beta. If anyone feels like tackling an improved set of configuration/administration/development tools, let us know!

Friday 8 May 2009


I am becoming increasingly fed up with the fear-mongering and misleading statistics being used by the campaign against the BC-STV electoral system being voted on next week in British Columbia.

I'm voting yes to STV for one very simple reason: it removes the fear of vote splitting, allowing me to indicate my true preferences. Period.

Have you ever heard any of the following statements?
  • "This is an NDP riding, there's no point even voting for someone else."
  • "This could be a close battle. Voting for the Green party might help the Liberal party get in."
  • "I like this party but I don't like their candidate in my riding."
With STV, you'll never have to hear those again. You can indicate your true first preference and, if they don't get elected, your vote gets counted for your next choice. No more vote splitting. And voting is dead simple: you write a "1" next to your first preference, a "2" next to your second preference, and so on.

Any electoral system is a complex balance between individual and group freedoms, degree of proportionality, cost, and many other factors. There is no "perfect" system. BC-STV may get tweaked over time but, in the meantime, the freedom to vote the way I want is reason enough to support it.

It's a shame that our province doesn't seem able to manage a real debate about this significant and important issue but don't be fooled by the mudslinging from either side. If you find the pro and con sites for STV in BC a little too heated, the Wikipedia articles on STV and FPTP (as well as on other voting systems) at least list both pros and cons for each. I also found the website of the Electoral Reform Society in the UK had useful and interesting reading (including pros and cons) on many different electoral systems. Although their stated preference for STV may bias their assessments of other systems, the site is much more balanced than any of the BC sites.

When to use a Seaside Component?

A recent StackOverflow question asked "When to use Seaside components, and when to use simple render objects?". This is a common challenge for new Seaside users (with the additional wrinkle of whether they should be implement a Brush thrown in for extra confusion).

To some extent these decision end up being subjective design decisions but there are some pretty compelling reasons why you might need to use a Component. I took a crack at answering the question but I encourage you to post or look for alternate answers there if you think mine is wrong in some way. I think the question is an excellent one so I'd also encourage you to upvote the question and/or answer if you think it is appropriate.

While we're on the topic, asking and answering Seaside questions on StackOverflow might help gain us some exposure and legitimacy. I actively monitor the RSS feed for Seaside questions and I'm guessing a few other developers do as well.

The main content of my answer was:

First of all, you are correct that you do not need to use a Component in order to access the Session. Seaside 2.9 moves #session up to a new class WAObject which makes it accessible to almost all Seaside objects (including Components) but you can definitely refer to WACurrentSession yourself for now in 2.8.

Components provide roughly the following functionality in 2.8:

  1. #renderContentOn: is called with an instance of whatever renderer class you specify in #rendererClass (instead of whatever renderer is in use when your object is asked to render itself)
  2. A hook (#updateUrl:) to allow updating the URL used by the renderer to generate links
  3. Hooks (#updateRoot:, #style, #script) to allow updating the HEAD section of the HTML document
  4. The ability to be the root of an Application
  5. Hooks (#updateStates:, #states) to make state backtracking easier
  6. A hook (#initialRequest:) to allow initialization based on the request that caused the Session to be created
  7. A facility (#children) to make sure all components below you will also have the above hooks called on them
  8. The ability to add Decorations
  9. The ability to show/answer/call (uses Decorations)
  10. Some convenience methods (#inform:, #isolate:, etc)

If you don't need any of the above, you don't need a Component. If you need any of the above, you pretty much do need a Component unless you want to implement the equivalent functionality on your own class.

The simplest metric is probably: if you intend to keep the object around between HTTP requests it should be a Component; if you intend to throw the object away and create it on each rendering pass it probably doesn't need to be. If you imagine an application that was displaying blog pages, you'd probably have Components for a menu, a blog roll, the blog body, each comment, and so on. You might want to factor out the reading of the blog's markup and generation of its HTML so that you could support different markups or different renderers and so that the comment Components could support the same markup. This could be done with a non-Component class that implements #renderOn: and could be created and used by other Components as needed.

Seaside 2.9 currently splits up the above functionality by making WAPresenter concrete and introducing WAPainter as its superclass. 1-3 above are implemented on WAPainter and 4-7 on WAPresenter so you have your choice of what to subclass depending on your needs. It also removes a lot of methods from WAPresenter and WAComponent in an effort to make them easier for end users to understand.

Wednesday 22 April 2009

Cincom starting work on 2.9

It's been a little while coming but it seems Cincom has begun to take a crack at porting Seaside 2.9. This is excellent news and it sounds like the first push hasn't been too painful, which provides some validation for our portability work. Hopefully this means we'll be able to iron out compatibility issues with VW before going to Beta.

Wednesday 15 April 2009

Seaside Tutorials from GemStone

James Foster announced that he has posted his Seaside tutorial materials online. The tutorial is released under a Creative Commons Attribution Non-Commercial Share-alike license and takes you through the basics of setting up an image, figuring out Smalltalk, and getting started with Seaside, Monticello, and then GLASS.

Seaside documentation is always welcomed by the community. Thanks to James and GemStone for making it available.

Tuesday 14 April 2009

Inspiring Service

My recent vacation to Portugal demonstrated the universally welcoming and easy going nature of its citizens. The weather was warm, the wind was fresh, the scenery was green and dotted with Spring blooms. The beaches were long and (because it was not yet Summer) uncrowded.

Still, the trip stands out most in my mind not for any of the above reasons but because it was essentially unmarred by lousy service. Depressingly, this seems so novel that I feel compelled to comment on the highlights.

Our flights on EasyJet proved far less stressful than on any other discount airline I have used. Sure, you're still paying for food and drinks and it isn't exactly luxury travel but the only weight restriction on hand luggage is that you be able to comfortably lift it overhead. And while you pay extra for every checked bag, they can weigh up to 32kg. Talk about removing stress from your travel planning. The food was at least fairly reasonably priced, the advertising audio pollution seemed less constant than on RyanAir, and the airplanes didn't look like they were decorated by Fisher Price. Despite being a discount airline, EasyJet seems to take some pride in providing a positive experience for its customers. Now if only they would eliminate the disturbingly animalistic charge for the door by assigning seats on check-in...

For the third time, we again booked our rental car with They partner with rental companies in each city to provide all-inclusive rentals: collision damage waiver, no deductible, third party liability, unlimited mileage, a second driver, etc. The only additional thing you pay is fuel and the prices are reasonable; to remove the 3000€ deductible, the couple in front of us were quoted nearly as much as we paid for the entire rental.

There are no more "Would you like to add X for only $Y?" questions and this completely takes the stress out of dealing with the rental companies on arrival. On a previous trip, we were charged some additional fee by the rental company but, upon return, HolidayAutos refunded the money to my credit card within a day or two of sending the receipt. And (!) they answer the call quickly when you phone. Note that the last time I checked the prices on the US (.com) version of the site didn't seem nearly as compelling.

One final example is Restaurante Oriente in Lisbon. This place was recommended in the EasyJet inflight magazine of all places and offered an excellent vegetarian buffet. The service was exceedingly friendly and, when the already-half-empty beer bottle we were pouring foamed over the top of the glass, it was replaced with a new bottle before the spill was even mopped up. This was way beyond necessary and (particularly since we were tourists and obviously unlikely return customers) totally unexpected.

Thanks and congratulations to these companies for providing excellent service and value to their customers.

Monday 30 March 2009

Russian Continuations

Andrey Larionov just posted a Russian translation of my article on the use of continuations in Seaside. Hopefully it's accurate... I certainly have no idea. :) He says he's going to try to start a series of articles on Seaside so keep an eye out for that if you can read Russian.

In other news, I'll be on vacation in Portugal for the next 10 days, likely without Internet access. I'm hoping the weather will get warmer than currently predicted but as long as the rain holds off I won't complain.

Wednesday 18 March 2009

Seaside at The Chasm

I've seen two references this week to Geoffrey Moore's Crossing the Chasm. I haven't read it yet but I've added it to my list.

Kent Beck describes the book's theory of market segments like this:

  1. Enthusiasts — will try new things for the sake of novely
  2. Innovators — will try new-ish things for the sake of business improvement in spite of some risks
  3. Early majority — will adopt proven products provided there is no perceived risk
  4. Late majority — will follow in adopting established products
  5. Laggards — the name says it all

He then goes on to highlight these observations of Moore's with regard to high-tech products:

  • The gap between innovators and the early majority is particularly wide (the “chasm” of the book title), stymying many promising innovations
  • Marketing is fundamentally word of mouth, but people in one segment don’t converse with people in other segments. This creates a chicken-and-egg problem in gaining traction in a segment.
  • Messages that work for one segment don’t work for the next. The time to switch is when a product seems to be gaining momentum, because that segment will soon be exhausted.

Eric Sink adds:

One of the ideas in [the] book is that new innovations don't go mainstream until they become a "whole product".

Now Kent is talking about JUnit Max and Eric is talking about Distributed Version Control Systems (like git, Mercurial, and Bazaar) but this got me thinking again about Seaside's positioning and how to grow our user community. I think GLASS, by providing integrated persistence, is a big positive step towards making Seaside seem like a "whole product". But what else is missing? Deployment/admin tools and documentation spring to my mind and I'm hoping to make a start on the latter with some of the posts on this blog. But what else?

Growing support by major Smalltalk vendors helps reduce the apparent risk within a small segment of the market but, for many people, Smalltalk itself is seen as a major risk. So part of making Seaside less appealing would involve either de-emphasizing its use of Smalltalk (not really going to work—people will notice eventually) or reducing the apparent risk of Smalltalk itself. That's no small task and the vendors, I'm certain, have this at the front of their minds. Still if anyone has any thoughts on how Seaside in particular can contribute to that effort, I would love to hear them.

One of the major perceived risks associated with Smalltalk, of course, is the relatively small number of developers using it. Thus we have a feedback loop there: more users means less risk, which means more users, and so on.

So three important questions, I think, are:

  1. What does Seaside need in order to be considered a complete product?
  2. What can Seaside do (other than growing the community) to reduce the perceived risk of adoption?
  3. What can Seaside do (other than reducing perceived risk) to grow the community?

No answers yet; just questions. If you have any thoughts, please share.

Wednesday 11 March 2009

Advanced users don't customize

I was scanning an old post of Joel Spolsky's and found this quote really rung true for me:

"But wait!" you say. "It's important to have options for advanced users who want to tweak their environments!" In reality, it's not as important as you think. ... Most advanced users use several computers regularly; they upgrade their computer every couple of years, they reinstall their operating system every three weeks. It's true that the first time they realized you could completely remap the keyboard in Word, they changed everything around to be more to their liking, but as soon as they upgraded to Windows 95 those settings got lost, and they weren't the same at work, and eventually they just stopped reconfiguring things. I've asked a lot of my "power user" friends about this; hardly any of them do any customization other than the bare minimum necessary to make their system behave reasonably.

It kind of surprised me that it was true, though: I used to be an obsessive preference tweaker but that animal urge seems to have died out along with the desire to immerse myself in video games until 5:00am. I still troll the preference dialogs of any new application, looking for options with as much clout as the Turbo button on old 386 machines, but I can usually close these dialogs without saving.

There are a few customizations I do any time I have a new computer (like deleting useless icons from the Dock or its equivalent). There are even customizations (like setting the refresh rate of the monitor higher than 60Hz so it doesn't hurt my eyes!) I do on every machine I touch. Firefox settings come with me whenever I copy my profile onto a new computer (I want my bookmarks). Other than that, if I can't share the customizations between computers (with an NFS-mounted .bashrc for example), I try to keep them to a minimum.

Of course, with Linux this issue is much less of a problem. I once had a system that I had to expand by putting in a second hard drive. As a result, I ended up with /home on its own drive. The next time I re-installed the operating system I was delighted to find my desktop and all my application settings exactly as I had left them.

Tuesday 10 March 2009

Book: The Long Tail

I found myself in a bookstore the other day and the limited selection of English books made it seem like time to check out The Long Tail (note the link is not to the same edition that I read).

The thesis is interesting: that consumer behaviour is changing due to increased selection, decreased distribution costs, better filtering and recommendation tools, and expanding access by amateurs to creative tools. The idea is that selling a few each of a million different things can now constitute a sizable and legitimate market. The history of mail order and consumerism in the United States also held my attention and there were pearls of interesting information about particular industries and companies thrown in.

Those were the good parts. But man do you have to wade through an enormous heaping pile of repetition to find them! I mean, I complained about the repetitiveness of Don't Think of an Elephant but The Long Tail makes that slender tome look like a particularly succinct haiku.

Anyone near me while I was reading will be able to confirm my level of frustration: every chapter or so I would snap, get up, and complain to whoever was nearest at the time (sorry!). Right down to the last chapter, we were still being treated—in every subsection!—to a paragraph-long definition of "long-tail economics" and its effects on commerce and consumers. Yes! Ok! We get it already!! The book should ha... I said we GET IT!!! The book should have been called The Long Read[1].

Basically The Long Tail should have just been an essay. In fact, it was just an essay so I wouldn't waste your money on the book. And if the original essay leaves you wanting, you can always try Wikipedia.

Don't Think of an Elephant also came out of a collection of essays so maybe this is a lesson for me (though it ought to be a lesson for authors). I bought Freakonomics at the same time as The Long Tail and I see it is also a collection of essays; so that doesn't thrill me with enthusiasm. Can anyone give me any comfort on that one? At this point even boring would be ok as long as it isn't repetitive...

[1] Credit for the title goes to Andy Stote. ;)

Tuesday 3 March 2009

Seaside 3: Server Adaptors

This is the next in a series of posts looking at changes in the upcoming Seaside release. Check out the other posts on partial continuations and exception handling.

The upcoming release of Seaside will feature some changes to the now-familiar WAKom. The existence of various subclasses like WAKomEncoded and WAKomEncoded39 was beginning to point at a usability problem and we wanted to facilitate running Seaside on multiple ports out of the same image.

First of all, we have introduced an abstract class, WAServerAdaptor. Server Adaptors provide an interface between Seaside and a particular server or connector (e.g. Comanche, Swazoo, AJP) and are able to start and stop server instances on the correct ports. Most importantly, they are also responsible for translating between Seaside's WAResponse and WARequest objects and the native requests and responses required by each server.

Server Adaptors are configured with a port number and a Request Handler. They are also configured with a Codec, which specifies the character conversion that should be performed when converting the requests and responses. Character encoding issues are complex, however, and we are still playing with those interfaces so I will leave that discussion for another time. Server Adaptors get registered with an instance of WAServerManager (currently a singleton) when they are created and the Server Manager coordinates starting and stopping the servers.

To create and start a new Comanche adaptor, you could simply execute:

adaptor := WAComancheAdaptor port: 8080.
adaptor start.

Alternatively, you can use the new Control Panel (implemented with OmniBrowser) to create and configure your adaptors. You can now create and run multiple adaptors of the same type. You can even configure multiple adaptors on the same port (perhaps to facilitate testing different servers or codecs) though only one can actually be running at any time.

Note that WAKom and its subclasses still exist for backwards compatibility in this release and will start an appropriately-configured instance of WAComancheAdaptor. These classes, however, only support running a single adaptor instance at a time and will be removed in a later release. Once created with WAKom, the adaptor will be visible in the Control Panel and can be manipulated there just like any other adaptor.

I mentioned that Server Adaptors can also be configured with a Request Handler. Why would you want to do that? By default, all Server Adaptors dispatch incoming requests to the same default Dispatcher. But perhaps you have an admin interface that you want to run on a different port so it can be firewalled to an internal network. Perhaps you want to make Seaside's web config tool available through an SSH tunnel. Or perhaps you have an XML-RPC interface or a status page for integration with a service monitoring tool. Maybe you just want to transition your application behind a load balancer to a new instance with different configuration options. Whatever the case, if you just want to configure a new Dispatcher using the web interface, the Control Panel has a context menu option called "Use new dispatcher" which will give you a new blank starting point on that Server Adaptor. If you have an existing Request Handler somewhere you can tell the Server Adaptor to use it like this:

adaptor requestHandler: myRequestHandler

Using a Dispatcher at the root will allow you to configure multiple Request Handlers at different subpaths but you could just as easily use an instance of WAApplication, RRRSSHandler, or any custom Request Handler subclass (more on this in a future post) if you want all requests to be handled in one place.

Sunday 1 March 2009

Seaside on Industry Misinterpretations

I spent some time this afternoon talking to James Robertson and Michael Lucas-Smith of Cincom for the Industry Interpretations podcast (episode 125). We talked a bit about the history of Seaside, partial continuations, the goals for the next release of Seaside, and some of the challenges (like getting debugging working). And probably some other things I've forgotten.

In fact, I know for certain that when we finished recording there was something I wished I had mentioned. I figured I'd blog about it when I posted about the podcast but, of course, now I have no idea what it was...

Update: The thing I forgot to mention on the podcast was another difference between a partial continuation and a full continuation. Evaluating a full continuation replaces the entire stack of the running process; a partial continuation can be evaluated—much like a block—so that, on completion, it returns to the context where it was evaluated.

On an unrelated note: I'm toying with the idea of making the trek to Potsdam for the German Squeak users meeting. Any other Seasiders planning to attend or have any idea how much someone with only elementary German would get out of it? :)

Friday 27 February 2009


I wanted to share a couple of photos from Fasnacht here in Konstanz this weekend. This is one festival that southern Germans take seriously. I'm not sure how well the costumes come across in the photos: when I saw individual people dressed up they seemed kind of silly; when I saw a few people hanging around in the same costume it felt corny; but when you get roving ganges of 30 or 40 of these guys ambling down the streets, only their eyes visible, it starts to have a serious impact on your psyche.
This traditional festival marks a transition from winter into spring. There are evil spirits (witches, goblins, etc.) and jester-like figures that taunt the evil spirits and frighten them away. And in the best tradition of human nature, even the clowns are creepy. At least I think they're clowns... or maybe they're evil characters too? Unfortunately my girlfriend was not with me to translate the culture.
This guy was cracking a 5m-long bullwhip on a crowded street. In North America, the good spirits could have frightened him off with threats of lawsuits!

The parade was actually a lot of fun. I particularly like the characters who sneak down behind the rows of spectators and surprise them with confetti or handfuls of straw rubbed in their hair. And my absolute favourite trick was seeing a huge furry monster looming menacingly over someone only to suddenly proffer a candy held delicately between thumb and index finger. This certainly beats Halloween for entertainment value, though I can't quite figure out why something called Fasnacht goes on for a whole week. Maybe I'll figure it out next year...

Thursday 26 February 2009

The crack of The Naughties

First of all, I apologize for the title: I was exposed to this name—so awful it's almost good—for our current decade only last week and felt compelled to throw it in. And yes, I realize I'm a bit late coming to this party.

Paul Graham's latest post talks about the challenges of maintaining the culture of his Hacker News site [link withheld to protect the innocent - you should be able to find it]. What I found interesting, though, was this almost offhand comment right at the end:

I feel like the addictiveness of games and social applications is still a mostly unsolved problem. The situation now is like it was with crack in the 1980s: we've invented terribly addictive new things, and we haven't yet evolved ways to protect ourselves from them. We will eventually, and that's one of the problems I hope to focus on next.
A way to protect ourselves from the crack that is the internet... Wikipedia safe injection sites? What do you have in mind, Paul?

Tuesday 24 February 2009

Zug Sprint

Last weekend we ran a successful Seaside sprint in Zug, Switzerland, hosted by Michael Davies.

With two days of solid work, we managed to close around 25 issues and were only occasionally distracted by LEGO Indiana Jones on the Wii. We also submitted a couple of fixes upstream for Comanche and Swazoo. We have nearly all the inter-package dependencies teased out now and the level of churn seems to be starting to ease a bit, which is quite exciting.

We have a very satisfying little centre of Seaside activity in this corner of the world right now.

Sunday 15 February 2009

Audio and video of my ESUG 2008 presentation

James posted the audio and video of my ESUG 2008 presentation on the evolution and architecture of Seaside. If you missed the talk and are interested in hearing how Seaside got going 7 years ago and where it might be heading, check it out.

Thanks James!

Wednesday 11 February 2009

Seaside 3: Partial Continuations

This is the second post in a series looking at the upcoming new release of Seaside. Check out the first post on exception handling.

Continuations in Seaside

Seaside is often referred to as a "continuation-based" web framework and certainly in its early days continuations were used throughout to work its magic. Seaside 2.8 still uses first-class continuations (more on what that means in a minute) in three different places:

  1. to abort normal request handling and immediately return a response;
  2. to interrupt a piece of code and resume it when the user clicks on a link or follows a redirect (to send cookies to the user, for example); and
  3. to implement Component call/answer.

The next upcoming release of Seaside, however, will completely eliminate the use of continuations within the core framework itself. Case 1 has been reimplemented using exceptions and the code for 2 and 3 moved to an optionally-loadable package. This means that you can now choose to install Seaside without using any continuations at all, which is good news for portability to a few Smalltalk dialects that don't currently support continuations.

At the same time, we are also replacing our use of full continuations with partial continuations and this article will look at what that means and why we are making this change. This stuff can get confusing (particularly while debugging it!) so don't worry if you have to let the information mellow and then come back and read it again. I've simplified a few things, sacrificing detail in the hopes of making the subject more comprehensible for people who are just curious about how it works. I'd appreciate any feedback on how well I've struck this balance.

What is a Continuation?

First of all, when I talk about continuations here, I'm talking about first-class continuations. Seaside also uses a continuation-passing style to implement its application render loop (this is the _k you see in Seaside URLs). This is a somewhat-related concept but is not what we're talking about today.

Continuations are often defined as "the remaining computation" but I think this can seem a bit obscure if you don't already understand them. To me, the simplest explanation is that a continuation saves a snapshot of a running process that you can resume later. You call a method, which calls another method, which calls another method, and so on and then at some point you create a snapshot of this chain of methods and save that snapshot object somewhere. At any point in the future you can restore it, abandoning the code you are currently running, and your program will be back in exactly the same place in exactly the same method as when you took the snapshot. That's a first-class continuation.

Smalltalk users should not find this too hard to come to terms with. When you save your Smalltalk image, you can open it later and be back exactly where you left off. You can open that saved image as many times as you like and return each time to the same state. If you save the image into a new file, you can still go back and load the old image. A continuation does basically the same thing but captures, instead of the whole image, only a single process.

Implementing Call and Answer

One of Seaside's most-demonstrated features is the ability to write multi-step tasks that query the user for information:

answer := self confirm: 'Do it?'.
answer ifTrue: [ self doItAlready ]

This is exactly the kind of thing we facilitate with continuations: we need to pause in the middle of this method to ask the user for feedback. If they ever answer the question, we want to resume the method where we left off. So let's look at how first-class continuations might be used to make this work.

Understanding the Diagrams

But first a word of explanation. The following diagrams depict context chains (though they are abstract enough that they could just as easily be a stack of frames). Every time you call a method or evaluate a block, a new context is created at the "top" of the chain. Every time a method returns or a block finishes, the topmost context is removed. The method context knows what method is being called, what object it was called on, and the value of any variables defined in the method. It also knows the context below it in the chain. If you need help understanding this process, take a look at this example illustration which shows the process step by step.

The diagrams below each represent a chain of contexts handling a single HTTP request. Each request is the result of clicking on a link and each causes the execution of a callback. Each callback eventually sends either #call: or #answer:.

The diagrams show the context chain at the point in time when #call: or #answer: is sent and then try to illustrate what happens next. The upward-pointing arrows show the progress as methods are called and the downward-pointing arrows show the progress as methods return. I show exceptions with a dashed arrow, the tail coming from the location where the exception is raised and the head pointing to the location where it is handled. In cases where a continuation has been saved, the diagrams show both the currently executing context chain and the saved one and the arrows behave as normal. Obviously these are very simplified illustrations; I'm more interested in getting the general idea across here than in the exact details.

To help make things clearer, each diagram is marked with a gray line. Everything above the gray line is user code: part of the callback that is being executed. Everything below the gray line, is part of the internal framework code: reading from sockets, looking up sessions, and so on.

A Naïve Implementation

Ok, so let's look at one possible implementation using continuations. Let's assume a user is staring at a web page with a link that says "do it". Clicking on that link will execute a callback with the example code shown above, which should prompt the user with the question "Do it?". While processing this request, the following things happen:

Full Continuation - Request 1

  1. The framework looks up the correct callback and executes it.
  2. During the callback (inside the #inform: method in the above example), the #call: message is sent.
  3. This results in every context being saved into a continuation for later use.
  4. An exception is signaled, which stops processing of the callback and returns control to the framework code.
  5. The framework continues its work and returns a response to the browser (in Seaside, a render phase would happen to allow the Components to generate the response, but I'm simplifying here).

The response to the browser should show the prompt "Do it?" and a link or button to confirm the action. When the user confirms the action, they trigger another callback, which will execute self answer: true. When this second request is received, the following happens:

Full Continuation - Request 2

  1. The framework looks up the correct callback and executes it.
  2. The callback sends #answer:.
  3. The current chain of contexts is thrown away and the exact contexts we previously saved in the continuation are retrieved and restored. Note that these methods will now return a second time. This is the weird part about continuations but remember it's no more weird than saving your Smalltalk image in the middle of a calculation. Each time you open the image you will get a result for the same calculation.
  4. Now that we have restored the saved context chain, execution resumes in the first callback as if the #call: method (remember, this is where we saved the continuation) had just returned.
  5. The restored callback finishes executing (in our example, it checks the value of answer and sends #doItAlready).
  6. The framework returns a response to the browser.

The problem here, and why I called this a naïve implementation, is that you can see the response is incorrectly returned to Request 1. The socket associated with Request 1 is, unfortunately, long gone and the browser is no longer waiting for a response over there. The browser is, in fact, waiting for a response that never arrives on the socket associated with Request 2. Ooops!

A (mostly) Working Call and Answer

So the first implementation doesn't work but hopefully you can see what was going on with the continuations. The problem is that, when we restore the continuation, we really don't want to abandon everything the framework is doing. At the very least, we need to keep the contexts that will return the response to the correct socket.

A simple way to limit the contexts captured by a continuation is to create a new process. A new process starts with a new, empty context chain, so when we create a continuation only the contexts in that chain will be captured. We can use a semaphore to cause the first process to wait while the new process handles the request. When the second process is finished, it signals the semaphore and the original process returns the response to the correct place.

This diagram shows exactly this (the contexts of the two processes are shown with different symbols):

New Process - Request 1

  1. At some point in the framework code, a new process is created and the original process waits on a semaphore.
  2. The new process finds and executes the correct callback.
  3. The callback sends #call:.
  4. A continuation is saved (note this time that the continuation extends only to the beginning of the new process).
  5. An exception is signaled, stopping callback processing and returning control to the framework.
  6. The framework creates a response and signals the semaphore.
  7. The original process resumes and returns the response to the browser.

So far, the only benefit here is that the continuation is smaller. But when the second request comes in, you'll see how this starts to solve our problem:

New Process - Request 2

  1. At some point in the framework code, a new process is created and the original process waits on a semaphore.
  2. The new process finds and executes the correct callback.
  3. The callback sends #answer:.
  4. The current chain of contexts is thrown away and the exact contexts we previously saved in the continuation are retrieved and restored (but note: this time only the contexts in the new process are abandoned; the suspended bottom process is unaffected).
  5. Now that we have restored the saved context chain, execution resumes as if the #call: method had just returned.
  6. The callback finishes executing.
  7. The framework creates a response and signals the semaphore to tell the bottom process it is finished.
  8. The original process resumes and returns the response (correctly!) to the browser.

So not only is our continuation smaller, but the second response actually makes it back to the right place. This, by the way, is the implementation used by Seaside 2.8 and earlier versions.

There are a few significant problems with this approach though:

  1. Doing multi-process synchronization adds complexity.
  2. Exceptions do not cross the boundary where the new process is created. That is, if you signal an exception in the second process the first process will never see it (technically, this could be simulated to some degree but that adds even more complexity). This means, for example, that error handling has to be done inside the new process. It also adds challenges when working with databases that use exceptions to mark objects as dirty or that key transaction information off the current process.
  3. Exceptions signaled after restoring a continuation will traverse the restored context chain. Also, when the exception is handled, the restored context chain will be unwound, not the abandoned one. Take a look at the framework code contexts highlighted in red in the last diagram: they never have a chance to finish executing and any ensure blocks they defined will never be executed. Trust me when I say that this can be the cause of some pretty subtle bugs.
  4. There is a trade-off between size/accuracy and convenience because of #2 and #3. If you start the new process right before the callback is executed, you get a smaller continuation and more accurate exception behaviour. Unfortunately, your exceptions don't propagate very far and your callbacks end up running in a different process from, say, your rendering code.
  5. Debugging sucks (at least in Squeak) when code depends on running in a certain process. I'm not sure if the debugger ever steps through the code with the actual process where the error occurred but it certainly doesn't always do so.

Partial Continuations

Enter partial continuations. A partial continuation simply means that, instead of saving the entire context chain, we save only the part we are interested in. And when we restore the partial continuation, we don't replace the existing context chain entirely; we only replace the part that we are not interested in. Let's see how they work.

Partial Continuation - Request 1

When the first request comes in, things work much the same as in our very first example so I won't number the steps. In fact, things work exactly the same except for one thing: using partial continuations, we can now specify the exact range of contexts to save in the continuation. In this case, we choose to save only the contexts that are part of the user (or callback) code. Remember the problems from the first implementation? The framework code is handling one particular HTTP request; these framework contexts would be completely useless to us when responding to any future request (and another request for the same URL is still a new request). Since a callback can span multiple HTTP requests, it is only those contexts that make up the callback that need to be saved and resumed later.

Remember also that the context chain is, in reality, much longer than shown in these diagrams: we might be storing five contexts now instead of, say, 40! A nice space savings.

Now let's look at the second request coming in. This illustration is a bit different and a little more complex because the context chain actually changes during execution, so I will explain it step by step:

Partial Continuation - Request 2

  1. A request comes in.
  2. The framework looks up the correct callback and executes it.
  3. The callback sends #answer:.
  4. We look up the saved partial continuation and, in place of the existing callback code, literally graft the saved contexts onto our current context chain by rewriting the senders. I'm waving my hands over the details but you'll have to trust me. The right side of the diagram shows the state after the contexts have been grafted in place. Note that all the framework contexts remain and we are still running in the same process. As far as Squeak is concerned, those methods were called in that order.
  5. We resume processing the saved callback as if the #call: method had just returned.
  6. Once the restored callback contexts have finished executing, they will return (because of the re-written sender) right back into the framework code that is handling the current request.
  7. A response is generated and returned, via the correct socket, to the browser.

Magic! It sure feels like it and it works beautifully. We have tiny saved continuations, we don't need a new process, and all our framework contexts get a chance to complete.


The partial continuation solution is currently implemented in the development version of Seaside and will be in the next release. Squeak and VisualWorks already support the implementation of partial continuations in Smalltalk code. GemStone is nearly finished adding support to their VM. Smalltalk implementations that cannot easily implement partial continuations have three choices:

  • they can simulate partial continuations to varying degrees of completeness using full continuations;
  • they can continue using a system similar to the one in Seaside 2.8; or
  • they can leave them out. As I mentioned earlier, we have removed all use of continuations from the core parts of Seaside: platforms can choose to simply omit support for #call: and this is now as simple as not providing the Seaside-Flow package.

By the way, at the same time as I was working my way through those subtle bugs I mentioned earlier, Eliot posted about stacks and contexts in the new Cog VM he's working on. As well as being very interesting reading, it shed some timely light on the meaning of primitive 198, which pointed me in the right direction and probably saved me an hour or two. Thanks Eliot! Check it out if you have the time.

I hope this was useful or interesting reading and would love your feedback on anything you found challenging or helpful to your understanding. Happy Seasiding.

Sunday 1 February 2009

Das Unheimliche

Last weekend I went for a walk along the Bodensee. It was a beautiful sunny crisp winter day and people were out in force, catching whatever warmth they could from the sun before it disappeared.

All of a sudden I was struck by the feeling of being an outsider walking through somebody else's world. This was a strange feeling for someone who had just spent six months living in china: I mean in Germany I look like everyone else; I dress like everyone else; I even (arguably!) speak the language.

One of our major frustrations in China was knowing that, no matter how long we lived there, we would always look like foreigners. We could live there for 30 years, speak fluent Manadarin with no trace of an accent, and still pay more at the market than a "local". We were treated differently (though, in many cases, for the better) and yet, at some level, we fit in. While the pigeonholing was frustrating, our role in society was "expat" and playing it was pretty straightforward.

Contrast that to (relatively small-town) Germany: here I'm not given the role of "foreigner". Here I look pretty much like everyone else so, instead of being a convincing expat, I sometimes feel like an unconvincing German. This reminded me of a blog post by Jeff Atwood from a while back about the Uncanny Valley hypothesis. This hypothesis relates to all kinds of things from robotics to animation and (Bill Higgins says) web-based user interfaces. The idea is that, as one thing gets closer to mimicking something else, the remaining differences make us feel increasingly uncomfortable. So, for example, an animated character (like the one above, from Polar Express) that is trying to look human may feel creepy but one that looks nothing like a real human (Homer Simpson, for example) may feel totally natural. By the way, if you haven't seen it, check out how far computer generated animation and motion capture can currently take us: meet Emily.

I'm off to practice being a more realistic German...

Saturday 24 January 2009

GLASS workshop

Cool... this place is offering a week-long workshop on Seaside with GLASS. The page is a bit confusing and light on details but it's cool that this kind of thing is being offered.

Monday 19 January 2009

The Year of Seaside?

I'm a few weeks late, but I just finished listening to James Robertson and Michael Lukas Smith doing the year in review on the Industry Misinterpretations podcast. I was amused to hear them use the phrase "the year of Seaside" (a reference to Randal Schwartz's predication for Smalltalk this year). There did seem to be a lot of Seaside-related news.

But now that 2008 is over, was it the year of Smalltalk (or Seaside)? Sure, there's a lot of Smalltalk code being written, but that's been true for as long as I've been involved in the community. We made some progress with Gartner; attendance at Smalltalk conferences was high (though it sounds like there are fears it could be low again next year); Randal's predication generated a buzz in the community; and certainly there has been a notable effort to generate publicity outside the community. But is it working?

Have people seen an increase in the size of the community? An increase in Smalltalk-related business? What are our metrics? Was 2008 The Year of Smalltalk?

Tuesday 13 January 2009

The Socratic Method

While cleaning out my browser's bookmarks (yes, I'm obsessive enough to do this once and a while), I stumbled across an article I had read by Rick Garlikov about teaching children using the Socratic Method. The Socratic Method, used extensively in the portrayal of Socrates in Plato's writings, is a form of philosophical exploration using questions to stimulate discussion and insight.

In this context, Garlikov is attempting to teach a third grade class about binary arithmetic by asking only questions and allowing the children to work out the answers themselves. A major part of the article is a transcript of this class, which lasted only 25 minutes and apparently resulted in 19 out of 22 students having "fully and excitedly participated and absorbed the entire material".

The article is a quick and inspiring read and I suggest you take a look. I sometimes think it would be nice to volunteer to work with a group of school children (eToys maybe?) and this would be an interesting approach to play with.

There is also a letter to his daughter with further details on Plato and the Socratic Method. If you are at all interested in pedagogy or philosophy, you might also want to check out some of his other articles. I seem to recall finding the article about mistakes made when teaching math interesting.