It was a huge pleasure to be speaking at a No Fluff Just Stuff
conference again, it's been much too long. This was a good show with a
lot of folks coming down from Vancouver, BC to attend.
This was an odd show for me, as we didn't do any Tapestry talks at all.
However, all three of my talks (an introduction to Cappuccino, and two
talks on Clojure) were well attended, with good questions and some fun
discussions between sessions. I'm looking forward to doing these same
sessions, with a number of improvements, in the Spring when NFJS starts
back up.
Interestingly, I was busy writing Clojure code almost continuously in
the back row of other speaker's sessions ... but this didn't stop me
from appreciating Scott Davis's great talks on Grails, and
on "deconstructing Web 2.0". Also, I had a lot of interaction with
Brian Goetz ("are all web application's broken"). As usual, as soon as
you mix Java with concurrency, it's a bit sobering. Tapestry helps
here, but is not a complete panacea against some of the "nightmare
scenarios" that may become more commonplace as the number of CPU cores
increases.
I'm getting more adept at advanced Clojure; I've been busy adapting the
concept of parameter destructuring to pulling data out of the request
path and query parameters.
(defaction increment-count {:path "count/increment"} [env]
[count :int] ; destructure the value after "/increment" as an integer
(send-redirect env (link env show-counter [(inc count)])))This defines a Cascade action, mapped to the "count/increment" path. A number is expected to follow (i.e., /count/increment/4) and the job of this action is to increment that value and redirect the user to the show-counter view. Cascade actions are still functions, thus the [env] (Cascade actions always take a single parameter, a map called "the environment" that provides access to Cascade values as well as Servlet API objects). The path destructuring follows: [count :int] which destructures the first "extra path" value as an integer. There's a number of built-in parsers referenced by keywords such as :int, or you can supply a function that takes a string and returns a value. If another pair of values is given, that applies to the next value in the path. I'm finding this a pretty elegant way to express this secondary aspect of mapping URLs to view and actions; there's additional syntax for destructuring query parameters instead of path values. I may extend this further, to handle default values for missing terms in the path. I try to capture some of this in my Clojure talks; the idea of growing the language up, adding the new features you need. From one perspective, this is just a domain specific language, but in the Lisp world, that concept is so deeply entrenched that there isn't even a word for it beyond "programming". This is one part of the overall Clojure picture that gets me very excited, and I'm continuing to struggle with how to express this to people for whom even the Lisp syntax is alien and off-putting. -- Posted By Howard to Tapestry Central at 9/22/2009 10:18:00 AM
