Creator of the Apache Tapestry web application framework and the Apache HiveMind dependency injection container. Howard has been an active member of the Java community since 1997. He specializes in all things Tapestry, including on-site Tapestry training and mentoring, but has lately been spreading out into fun new areas including functional programming (with Clojure), and NodeJS. Howard is a DZone MVB and is not an employee of DZone and has posted 80 posts at DZone. You can read more from them at their website. View Full User Profile

Progress on Cascade

11.09.2009
| 3357 views |
  • submit to reddit
In spare minutes (and during sessions at ApacheCon), I've been continuing to work on Cascade. It's been a great learning exercise for me, pushing my understanding of both Clojure and functional programming in general ... and especially, some pretty advanced meta-programming with macros.

I'm also using Cascade as a kind of test bed for ideas that will eventually appear in Tapestry.

Not everything turns out exactly as I've planned. For example, I've been very excited about invariants, portions of the rendered DOM that could be cached from one request to another, to speed up the rendering. Like Tapestry, Cascade views render a DOM structure which can be manipulated (in an intermediate stage) before being streamed as text. This is a useful and powerful concept in a number of ways.

My thinking has been that a typical view will contain sections of the template that are invariant: unchanging, and that there would be a benefit to building that sub-section of the DOM once and reusing it efficiently in later renderings of the view.

Clojure template forms are processed by macros to become normal Clojure code. Thus something like (template :p [ "Hello" ]) will be transformed into code, approximately (element-node :p nil (combine (text-node "Hello"))). My approach was to tag the new Clojure code forms (the list consisting of element-node, :p, etc.) with meta data to identify it as invariant. Eventually this would propagate up to a higher level and code to manage a cache would be wrapped around it: (or (read-view-cache 97) (update-view-cache 97 (element-node :p ...

Fun stuff ... until I put it into practice (after a fair amount of debugging) and discovered that in the views I've created so far (for testing purposes), the number of nodes that can be cached is low; any use of a symbol or a function call mixed into the template "taints" it as variant. I wasn't set up to do performance measurements, but my gut feeling is that the overhead of managing the caches would overshadow the savings from the small islands of reused DOM nodes.

Back to Cascade as a learning experience: just because this didn't work out doesn't mean I didn't learn a lot from heading down that direction, and certainly the amount of code it took was quite small. I have it stored in a branch in case I ever want to give it another shot.

I will have all the basic features of Cascade implemented pretty soon; I'm looking forward to seeing what the larger Clojure community makes of it. In the meantime, it has served as a great way for me to dig deep into Clojure ... I'll be putting together more sessions for NoFluffJustStuff and more articles for the companion magazine based on all this.

From http://tapestryjava.blogspot.com

Published at DZone with permission of Howard Lewis Ship, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Howard Lewis Ship replied on Mon, 2009/11/09 - 10:29am

I'd love to know the "algorithm" used to promote my blog entries up to DZone articles.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.