SushiStore and Pier
Posted November 4, 2013on:
Five years ago Lukas Renggli and team took SushiStore out of the base Seaside distribution. That annoyed me no end. To me, it meant they had removed the sole clear example of a website in Seaside. The rest were just examples of tiny widgets that didn’t add up to a full website. Five years have past and I have a new view on that decision. It’s more nuanced than my opinion of five years ago.
What I couldn’t see five years ago was that while the website was comprehensible to an end user, to a programmer looking at how it was implemented, there were some problems. In short WAStore, the foundation class or root class of SushiStore, lead a person on a convoluted journey. A lot goes on in a very small area. Now that I’m looking at Lisp in a book called “Land Of Lisp” SushiStore has the density of a Lisp program. Avi was a Lisp programmer, so maybe he was used to packing a staggering amount in a small area.
The foundation of any Seaside website is going to be some kind of Compsite pattern straight out of the Design Pattern Smalltalk Companion. Seaside follows that pretty closely. It also adds Decorations. Though, it’s worth noting that the DPSC does not say much about how to implement the Composite and Decorator patterns. It will not tell you how to write #addDecoration: or #decorationChainDo: or #childrenDo:. The DPSC does describe the Decorator pattern using VisualWorks of about twenty years ago. Squeak has no native implementation of the Decorator pattern that I can see in Morphic or anywhere, so I posit that the Decoration implementation came from VisualWorks to Squeak.
At any rate, the Composite pattern is the foundation of any Seaside application. You create a root. Perhaps you extend the tree structure downward and outward with #children. Or you add a widget that is rendered from your root with #render (or with div id: ‘foo’; with: which does the same thing). But here’s where it gets hairy: what kinds of nodes are you going to have?
SushiStore starts with a node that renders some HTML. Then it has a node that contains a subclass of WATask. In this case it’s WAStoreTask. That’s a kind of Strategy pattern node, I think. It contains the algorithm or steps of your website/program. Then there are other nodes called to fill ivars like task, main, cart, and cartView. And then, on top of that, you are calling continuations on some of these ivars. In terms of following the Composite pattern that can be a surreal experience, because the Composite pattern just … stops… and then picks up somewhere else. This leap is managed by decorations added with #isolate:
So, in terms following a textbook Composite pattern, this is quite a lot going on in quite a small space. I imagine this is the kind of thing that made Dijkstra upset about the GOTO command. This morning I’m looking in “Land Of Lisp” and there’s a long disclaimer about the loop and format commands. The author tells at length that though these commands are impure, but they sure are useful. Ah, OK. As far as I’m concerned a hand on a hammer is a hand on a hammer.
And I guess I cannot be too aloof of this ideological concern, because I can see now that SushiStore is extremely dense. It’s disorienting. And who had some solutions to the fruit cup chaos of Sushi Store, why, Lukas Renggli did. Did things get clearer? Yes the did. Was there less complexity. Nope. The fusion of Pier and SmallWiki created a much more complex beast than SushiStore. But if you have some DPSC patterns under your belt, you are amazed at how cleanly Lukas makes patterns work together. It’s remarkable. And yet, I sort of wonder if the cure isn’t just as bad as the disease.
As far as I can tell, Lukas saw a number of problems with SushiStore and came up with amazing solutions for each of them. But what sort of gets me about Pier is how the original problems are so totally obscured by staggeringly innovative solutions.
The Composite pattern in Pier is uniform. If SushiStore’s Composite pattern is a mash of behaviour and state, then the Composite pattern in Pier is purely state. It does one job. All the behaviour has been pulled out and put in Visitor pattern classes that iterate over the clean state-only Composite. That’s pretty nifty.
Yet, it abandons continuations entirely. I have Pier3 loaded in a Squeak image and there are no senders of #call: anywhere. I don’t think that clean Composite pattern with its Visitor pattern can use continuations at all. The commands are executed with Command patterns. And I think you can add Composites inside the main Composite pattern in the form of structures and widgets and such.
The WATask Strategy class? Gone. It has no place in the Composite pattern in Pier. My knowledge of Pier is only starting, so I guess there is lots of space around the clean, state only Composite that allows for different algorithms.
Looking at SushiStore, I think that what is needed is a generic Composite structure for a beginner to make a Seaside website with. Perhaps there would be some standard ivars that could be nodes. Then those nodes could be filled with widgets. And those same ivars would be the pedestals continuations could stand on to move orthogonally above the Composite pattern. A nice map of a standard Composite pattern with ivars/nodes to extend as needed would be a great map for a person starting with Seaside to use. As usual, Lukas saw something similar, and as usual he went about three steps better.
He created the Environment page. Using the SmallWiki tools of SmallCC and Pier syntax, you have a base, bottom, “under page” presented to you. He saw that a Seaside application needs a bottom page or map to build on top of and he made it changeable like any wiki page. Very clever. At bottom, any Seaside application is one page – the one you start on. From there you’re swapping components in and out of ivars or calling continuations. Lukas sees the problems and creates amazing solutions. And yet, it would be nice if the problems were elucidated clearly. Instead, the dazzling solutions erase the original problems altogether.
My ultimate point is that by revisiting the original problems, I think I see a point in the evolution of Seaside where it reached a crossroads. That moment was somewhere in 2008, I think. There are a number of problems to getting started with Seaside. There are almost too many possibilities. It can be overwhelming. For each problem, Lukas came up with a solution. I want to emphasize that I believe they weren’t the only solutions. It’s hard to argue against such a brilliant programmer. Yet I think to revisit the evolution of Seaside is to see the problems that grew into Pier with fresh eyes. There is the Lukas way of Seaside. Yes. But I don’t think it was ever the only way.
A standard Composite pattern where every node is either behaviour or state is viable. Seemed to work for Avi. Seaside adoption hasn’t exactly exploded in the past five years. I think that’s because the evolution toward Pier as the paramount solution made things more overwhelming for a beginner, not less.