Archive for July, 2006

Writing AJAX applications in Haskell

How easy is it to write an AJAX application in Haskell? Very easy indeed. Here’s a little example of an AJAX server that echoes JSON requests:

module Main where

import Data.Maybe (fromJust)
import JSON
import Network.NewCGI

jsonEcho :: CGI CGIResult
jsonEcho = do jsonString <- getInput "json"
              setHeader "Content-type" "application/x-javascript"
              output $ (stringify . fromJust . parse . fromJust) jsonString

main = runCGI jsonEcho

To get this to compile you need the following haskell libraries: Fast Packed Strings (needed by haskell-cgi), XHTML combinators (needed by haskell-cgi), haskell-cgi, and JSON.hs

The resulting executable can be installed on any web server that supports cgi scripts. For my tests I configured apache with cgi execution enabled in user directories. You can download the little example app here. The client code employs the json and prototype Javascript libraries.

The JSON.hs file included in this distribution is a slightly modified version of the one listed above which adds support for Ints.

3 comments July 13th, 2006 matthias

Haskell typing weirdness (pt 0 of n+1)

I have been trying to get some real work done with Haskell - shock, horror! As part of that I am using the excellent HaskellDB combinator library for type-safe and composable database operations. HaskellDB employs some advanced type constructs such as phantom types, which can result in rather complex types that make analyis of type errors a bit of a challenge. It also makes it tricky to produce type annotations for the code by hand, e.g. for documentation purposes. One can of course ask haskell for the type, and then just stick that in the annotation, but the types one gets this way do not make for pleasent reading and require exposure of a whole bunch of HaskellDB’s typing guts.

By far the most weird typing issue I ran into though is when I had two identical (in all but name) functions, one of which was being used in my code and the other one wasn’t:

intervalIds = map $ flip (!) TaskTime.xid -- used
intervalIds' = map $ flip (!) TaskTime.xid -- not used

The type checker chokes on the latter with

No instance for (Select (Attr Task_time.Id Int) a a1)
  arising from use of `!' at Model.hs:59:26-28
Probable fix:
  add an instance declaration for (Select (Attr Task_time.Id Int)
                      a
                      a1)
In the first argument of `flip', namely `(!)'
In the second argument of `($)', namely `flip (!) Task_time.xid'
In the definition of `intervalIds'':
intervalIds' = map $ (flip (!) Task_time.xid)

So it looks like the use of intervalIds places sufficient constraints on the typing to make the function typable, and the absence of such constraints for intervalIds' results in an untypable expression.

On reflection this is not really surprising. A number of the advanced typing features of haskell are not amenable to type inference and hence require explicit type annotations. However, as explained above, coming up with these annotations is not always easy or desirable.

Add comment July 7th, 2006 matthias

Wicket

I recently used wicket to knock up a simple web shop example for our ExproRetail product and found it to be a fairly pleasant experience.

Wicket is (yet another) Java web framework but it distinguishes itself from many others with the following features:

  • No XML configuration
  • Very clean page templates
  • High level of abstraction - User code rarely has to refer to HTTP concepts

Writing a Wicket app is rather more like writing an event-based desktop application than a web application. For example, to render a link and react when it’s clicked all that’s needed is:

In the template:

<a wicket:id="mylink">Click me</a>

In the code:

add(new Link("mylink") {
  public void onClick() {
    // Do something when link clicked...
  }
});

Similarly, to handle a form submission you could create a TextField, give it a model to read/write its data to and add it to a Form. In either case there is no need to worry about constructing specific URLs, query parameters, HTML escaping etc.

Templates are just standard XHTML with a sprinkling of wicket attributes. When Wicket renders the template and encounters a wicket:id it looks for a matching component to render the tagged element. This is a simple and powerful system very similar to that used by the Python web kit nevow.

Wicket also makes it very easy to create custom “widgets”: Simply extend from an appropriate subclass of Component and provide a snippet of XHTML (if needed). To use your widget, all that’s needed is a simple add(new YourComponent(...)).

With version 1.2 there’s lots of AJAXy goodness too but I’ve yet to try this myself and the docs seem to be slipping behind a little.

The downside to all this convenience, at least for any reasonably busy site, is that Wicket stores a lot of state in user sessions. Some of the time gained letting Wicket manage everything may be lost ensuring that session usage is kept under control.

2 comments July 6th, 2006 mporter

Estimating the number of blog subscriptions

Unlike traditional website visitors, most readers of a blog use a news aggregator to periodically pull new items from the blog’s syndication feed. As a result, the co-relation between the number of requests and the number of times an item is read is broken, and to confuse things even more - many readers use a public aggregator service which saves the feed to a central repository and serves the saved entries to many readers. For such services, growth in the number of subscribers is not represented by an increase in the number of requests made.

To get a rough estimate of the number of subscribers to a feed we need to separate between requests made by public services on behalf of more than one user, and requests made by individual news aggregators.

If you too are curious about the number of subscribers to your blog (and have access to the HTTP access log of the server hosting it) you can give my little script, Blogalizer, a try.

Continue Reading 3 comments July 4th, 2006 Tom Berger

Java equality for testing

I wanted to define equality functions for unit testing purposes. The general pattern is that I’ll call a method that returns a complex data structure. I’ll want to test if the data structure matches the sample data structure in my test. Frequently the definition of Object.equals() won’t test equality in the way I wants to - it will depend on identity. I’ve defined an equality function that generally provides what I need, and can be easily specialised. There are quite a few things to consider, so I thought I’d write this article about it.

Continue Reading 1 comment July 4th, 2006 david

Next Posts

Calendar

July 2006
M T W T F S S
« Jun   Aug »
 12
3456789
10111213141516
17181920212223
24252627282930
31  

Posts by Month

Posts by Category