Custom Search

Wednesday, December 30, 2009

Why most web frameworks suck

Compared to desktop GUI frameworks, most web frameworks pretty much suck. Of course, web frameworks are like editors and X window managers - nearly everybody hacks one together, so there are more available than can reasonably be known by one person. If I've missed one that doesn't suffer from the problems I mention, please let me know about it!

So consider the simple act of adding a button that arranges to run a single bit of code. In a desktop app and OO language, that looks something like:

  ActionPane.AddButton(text="Do It!", callback=DoIt, pack=LEFT)

I.e. - you tell the system you need a button, how to label it, what code to run when it's pushed, and a little bit of information about how to position it.

In a web application frameworks, getting that effect typically involves adding text to a template somewhere, then tweaking the global "routing" configuration so whatever event the user generates by clicking the button in their browser actually invokes the DoIt code. Instead of editing one file - that's the same language as the code to DoIt - you're editing as many as three files, in three languages. If you're really lucky, two of them are XML with different namespaces, so it only feels like two languages.

Having to specify the routing by hand is particularly egregious. It's sort of like having to use the windowing systems ID for the button to find the callback code for the button. No competent desktop programmer would put up with that for long. If nothing else, they'd write a wrapper function to hide that from them.

Templates are a relic of a bygone era. In the best case, you're editing XML with multiple namespaces - which is ugly enough. But there's a good chance you're editing XML intermingled with something else. In the worst case, that looks just enough like XML to confuse an XML editor, but I hope everyone is beyond that.

Apache's Tapestry manages to avoid all that by using Java's introspection facilities to find methods in the code and automatically tie them back to invocations in the templates. The downside is that this exposes all your code in the templates, which is maybe not such a good idea. The problem is that half the application uses templates that need to refer to code objects, but aren't written in code themselves.

Templates were intended to separate the presentation of the data from the code that generated it, but I've never seen a templating system that did that properly. In particular, to present a list of data items of unknown length, either the templating language has to have a method of coding a display that's repeated for the sequence, or the code has to emit bits of display control to separate items in the sequence.

The reason I call this a relic of a bygone era is that CSS was supposed to have allowed the presentation control to be moved into the style files. While everyone uses style files to control presentation, people still seem stuck with doing the actual page coding in templates. If your team is driven by non-programmers who create the template files, this may be a desirable situation. But if your team is all programmers, it pretty much sucks for them - even if they don't realize it.

If, on the other hand, the template's could be replaced by code, with the presentation controlled by CSS, a lot of problems vanish. Programmers could work in one language - the code. CSS doesn't need to reference code objects, it just needs to reference known tags, class or id values - which are part of the output data, not part of the code. This is essentially what the desktop applications are doing.

One major difference is that desktop applications have to call code to create the structures that describe the UI. The UI for web apps can be described by a simple text string. Because of this, even in tools that embed the template in the code, the template is often text or data, and not actually code. This then requires code to walk that structure, generating the text and plugging in values where it's needed. Unless the structure in question allows sharing bits between it, this makes sharing objects between different parts of the UI difficult. If the UI is described by objects with their own intelligence, it becomes easy to share those objects between different parts of the UI, even if it looks like a template structure.

Like I said, there's no fundamental reason that this can't be done - it's just that people don't. The one exception I know of is the Seaside framework. Unfortunately, it's written in Smalltalk, which is even worse about playing well with others than LISP. It's also not suitable for use with Clojure, as it's unabashedly OO.

I've spent the last few days contemplating what a Seaside like framework for Clojure should look like. I've got a rough design, and hope to have some sample code working in the near future. At that point, I'll post a design for review.

Saturday, December 26, 2009

First Clojure project: an x10 web page

Ok, the clojure project: Set up a web server on my lan that lets me control the x10-connected appliances on my network from my android phone. There are a number of tools to do this - Heyu and Mr.House come to mind, plus various web things that live on top of things like bottlerocket. Nothing really fits my needs, though - the simpler stuff is very simple, the larger products are formatted for a desktop browser, not a phone. I want the latter formatting, and a few extra facilities - groups of devices and macros, and not a lot else.

So the first part is - done. I can now toggle x10 devices on and off from Clojure. This just used off-the-shelf Java libraries, and most of the hour or so it took was spent dealing with the Java environment and documentation

The hard part is going to be the web interface. That will be a Java servlet, probably using Jetty as the server. However, it needs a framework - and there aren't any I consider useable already available for clojure.

First reflections on Clojure

I'm always looking for new programming languages - they are, after all, the tools of my trade. So new languages that might make me more productive, or give me a new insight into programming are always of interest. The latest language to catch my attention is Clojure (http://clojure.org/).

Clojure has been described as "LISP reloaded". To me, it's just a modern LISP. It's got some syntax quirks that separate it from other LISPs, but nothing really major is different about it as a language.

One thing that is different is the attitude of the community - in particular the author. Rather than wanting everything to be LISP, Rich Hickey is quite happy to leverage the work of other languages to make things easy his users - and for him. It runs on top of the Java Virtual Machine, meaning he doesn't have to invent and then implement a VM just for his system. It also solves one of the major problems that drove me from LISP earlier, in that Clojure, unlike earlier LISPs - "plays well with others." As a Clojure programmer, I can use Java libraries, which means I can access most system facilities that other LISPs could only get to with difficulty. I can write Clojure code and let it be used inside Java applications. I can even share data with the rest of the system as well as Java ever does.

Of course, just being a LISP with it's major problems fixed isn't really enough to cause me to learn a language. Clojure was designed from the ground up to work well in concurrent environments, which are becoming the way to leverage power in the current desktop environment. So all the native types and most of the native structures are immutable. This means most of your programming is going to take on a functional style, which makes using LISP - the parent of all the functional programming language - a natural choice. The mutable data structures are there to help with concurrency, and allow mutation under different conditions, usually using high-level mechanisms that don't have the problems associated with the usual locks. Locks are even available if that turns out to be the right answer.

As a final draw, people have demonstrated that you can use Clojure to create Android applications, which is something else I've wanted to get into.

So, I've been through some tutorials, read the book, and installed Clojure a couple of times. I've picked a couple of likely projects, and even identified the Java libraries I'll need for them so I can work on the interesting part of the projects, and not have to deal with either hardware details that are largely irrelevant, or writing something for the dozenth time.

So far, I'm impressed. There are a few warts, but mostly the parts fit together well. It's got all the features that drew me to LISP long ago, and the Java integration seems like it's going to deal with all the problems that drove me away from LISP. And the concurrency tools will, if nothing else, provide new insights into concurrent programming.

Friday, December 25, 2009

Joining the 21st century

Yeah, it's christmas - so it's a week early for new years resolutions. But mine for this year is to drag my ass off the 20th centruy web, and start using the 21st century tools that are available. Like having a facebook profile, and a blog that actually gets used. And maybe even connecting them up via twitter.