Chris Nelson's interview with TheServerSide has been published. In the interview he talks about Trails, Rails and Tapestry. The interview is full video here. Alas, viewing the interview requires an install of the obnoxious RealPlayer.
Thursday, June 29, 2006
Wednesday, June 28, 2006
Just found out about www.javaref.com which is a single site that contains JavaDoc for over 80 open source frameworks. The site itself is built on Tapestry 3, Tomcat and MySQL and uses a lot of slick Ajax effects, including an update-in-place data grid and nice tab views, plus a few kinds of "spring loaded" dialogs. It's always gratifying to see people do something really nice and really slick (and really useful) with Tapestry.
Tuesday, June 20, 2006
Although the earliest adventures used just a simple VERB NOUN syntax, the Infocom games had much more powerful parsers that could understand more complete and natural inputs such as "take all the rings but the silver one" or "put the red battery inside the lantern".
In high school (say, around 1982), I wrote a very stupid, very simple adventure game, "Obelisk Adventure", in PDP-11 Basic. It had pointless quests, a maze with a big nasty rat (the maze wasn't mappable, because it randomly moved your stuff around). I think I also remember an endless hallway (poorly implemented). I also implemented a few similar adventures on my home computer (first a Challenger 1P, later an Atari 800). This was my claim to fame for a while, as pathetic as it appears in retrospect.
These games didn't go away after Infocom and the other publishers disbanded due to the onslaught of more graphic games (such as Castle Wolfenstein and, eventually, Doom and Quake). The underlying virtual machine was reverse engineered and an open source community grew up around virtual machine implementations, as well as languages and tools that compiled down to that machine: Graham Nelson's Inform.
The Inform language is a mix of general purpose features, and a lot of very domain specific stuff -- specific to the idea of simulating a world of rooms, objects and actors, and specific to the hooks of the natural language parser. Here's some Inform 6 source, stolen from the Wikipedia entry:
Constant Story "HELLO WIKIPEDIA"; Constant Headline "^An Interactive Example^"; Include "Parser"; Include "VerbLib"; [ Initialise; location = Living_Room; "Hello World"; ]; Object Kitchen "Kitchen"; Object Front_Door "Front Door"; Object Living_Room "Living Room" with description "A comfortably furnished living room.", n_to Kitchen, s_to Front_Door, has light; Object -> Salesman "insurance salesman" with name 'insurance' 'salesman' 'man', description "An insurance salesman in a tacky polyester suit. He seems eager to speak to you.", before [; Listen: move Insurance_Paperwork to player; "The salesman bores you with a discussion of life insurance policies. From his briefcase he pulls some paperwork which he hands to you."; ], has animate; Object -> -> Briefcase "briefcase" with name 'briefcase' 'case', description "A slightly worn, black briefcase.", has container; Object -> -> -> Insurance_Paperwork "insurance paperwork" with name 'paperwork' 'papers' 'insurance' 'documents' 'forms', description "Page after page of small legalese."; Include "Grammar";
And you can do a lot with that language, and I've occasionally looked into trying my hand at it. But it never seemed like a good use of my time (if I'm not working on Tapestry, I try to find things that get me away from my computer, and preferably, out of my house).
... so I was stunned and amazed when I saw the new version of Inform, Inform 7. The language above is gone and replaced with a natural language of tremendous power and flexibility. The same example, also off Wikipedia, in the new language:
"HELLO WIKIPEDIA" by A Wikipedia Contributor The story headline is "An Interactive Example". The Living Room is a room. "A comfortably furnished living room." The Kitchen is north of the Living Room. The Front Door is south of the Living Room. The insurance salesman is a man in the Living Room. The description is "An insurance salesman in a tacky polyester suit. He seems eager to speak to you." Understand "man" as the insurance salesman. A briefcase is carried by the insurance salesman. The description is "A slightly worn, black briefcase." Understand "case" as the briefcase. The insurance paperwork is in the briefcase. The description is "Page after page of small legalese." Understand "papers" or "documents" or "forms" as the paperwork. Instead of listening to the insurance salesman: say "The salesman bores you with a discussion of life insurance policies. From his briefcase he pulls some paperwork which he hands to you."; now the player carries the insurance paperwork.
Graham's goal was to allow non-programmers to write interactive fiction. The "code" is readable by human and compiler alike. Many of the examples in the documentation maintain this look, even when doing complex things like adding new verbs to the grammar (though some of the advanced examples are less natural language, and occasionally some Inform 6 code is injected as well).
What's important is that is not COBOL. It's not complex and rigid and verbose ... it is, in fact, very concise and the parser is very, very flexible and adaptive to the user. For example, you can easily talk about related nouns in a pretty random order. By editting the source, you can discuss the briefcase before describing the insurance salesman ... I tried this, juggling the order of the paragraphs in the example and the game still compiled and worked identically.
It also has a lot of cool features, such as
instead of reading the letter the third time, say "Re-reading the letter isn't going to change what it says." The language is expressive enough to understand lots of dependent information, such as actions occuring in sequence, related to the "game clock", or repetition. Much of the game logic takes the form of "before" and "instead of" rules around normal actions, built into the language (and its standard library).
This language is partnered with a special purpose IDE and reams of excellent, hyperlinked, integrated documentation and examples. Further, the IDE has built in regression testing capabilities (you can play a game within the IDE and record the responses, then later play back the game after changing the source). The IDE also generates maps and indexes of the game.
Sure, he's been working on this for a long time (Inform 6 is nearly ten years old). But the possibilities of this, taken out of this specific domain, are impressive. Imagine writing complex behaviors in succinct natural language instead of verbose XML. I'm normally against MDA approaches, but I think this kind of natural language deserves a careful assessment to see where it can be used within the enterprise.
Saturday, June 10, 2006
Friday, June 09, 2006
The "little" project that's taken up a lot of my time over the last year, Vaisala StrikeNet is now online. Vaisala is my client in Tucson, AZ that I've occasionally mentioned. It's a bit of a niche application (Vaisala tracks lightning strikes across North America, mostly for use by the insurance industry) but it is written using Tapestry 4 ... in fact, I made improvements to Tapestry 4 based on "rough edges" I found while coding this application.
Monday, June 05, 2006
Just stumbled across a blog about Lazy Bean instantiation in Spring 2.0. This is kind of funny to me ... lazy instantiation is so important, so part of the base line of IoC container functionality, that I just assumed Spring already did this.
Update: Spring has had lazy instantiation since at least 1.2, but it isn't on by default.
For the record: this is one of the essential services provided by HiveMind since day 1. HiveMind lazily instantiates everything it can, and is smart, using a pair of proxies for efficiency.
Why a pair? For threading efficiency. The outer proxy is visible to the world and delegates (initially) to the inner proxy. The inner proxy has its methods synchronized as it is responsible for thread-safe lazy instantiation. Once the service (and its interceptors) are instantiated, the inner proxy replaces itself inside the outer proxy. That is, once the service is instantiated, the outer proxy delegates directly to the service implementation, and the inner proxy is no longer needed (it is released to the garbage collector).
Doing things this way is a great idea, but not my great idea. It was suggested a long ways back by someone in the HiveMind community. I'd like to extend proper credit on this, but my memory is weak.
Using double proxies is a very powerful technique, since it ensures thread-safe, just-in-time instantiation of the service, without paying the cost of synchronizing every method in the outer proxy. It's an example of what an IoC container buys you ... I don't think you'd want to code three implementations of every service interface manually, but if you skimp, you undercut the performance and scalability of your app. Using HiveMind, two of the three implementations (the outer and inner proxies) are just provided for you.
So, that's a new answer to one of the more frequent questions posed to me: Why does Tapestry use HiveMind and not Spring?. A: Spring does not provide all the capabilities that Tapestry requires, such as lazy instantiation. Tapestry consists of about 200 services, but very few of those are needed at startup, and a percentage will not be used in most applications. Lazy instantation is a huge win for Tapestry.
Futher, HiveMind's approach to lazy instantiation and proxies means that you can have mutually dependant services ... services that are injected into each other. The proxies, and the lazy instantiaton, means that you bypass the normal chicken-and-the-egg problem of which service to instantiate first. I've used this technique to break untestable, monolithic code into two halves that can each be properly unit tested.
Back to Spring ... now that it looks like Spring 2.0 has lazy instantiation, I have to question the fact that it defaults to OFF.
Sunday, June 04, 2006
Just got back from three weeks away from everything: first a week at JavaOne, where Tapestry received a Duke's Choice Award in the open source category. From there, it was two weeks on the island of Hawaii (the "big island" ... it's about the size of Connecticut). That was two weeks where I had virtually no internet connection (certainly not at the cottage I was staying at) and really, really didn't even think about Tapestry. Instead, it's been horseback riding, hiking, snorkeling and boogie boarding. Sun, surf and sand. That's quite a change, and a good break (normally, I close my eyes and start seeing code). This was good for me, I'm feeling just a little less frantic than before ... I've been doing too much for so long that I've forgotten what it means to relax. I'm literally tan, fit and well-rested.
I'm also pretty much done with my work at Vaisala, with that app going live in a couple of days. I'm looking forward to a chance to focus on Tapestry full time for a bit, I have code for Tapestry 5 to write, and updates to labs and examples and documentation, new sessions to write (such as for OSCON 2006). Meanwhile, Jesse and Brian have been kicking ass on Tapestry 4 and Tapestry 3, and Geoff looks ready to get Spindle upgraded to Tapestry 4. So there's a lot going on.
I'm also fired up to get people's attention on Tapestry. We need more articles and more evangelism and more books on Tapestry and I'll have more time to spearhead and motivate people on those lines. I'm already beginning to think of 2006 as the Summer of Tapestry.