[Haskell-cafe] Web application frameworks (was: [Haskell] Re: Trying On Learn Haskell Web Server)

Graham Klyne GK at ninebynine.org
Tue Mar 7 04:33:24 EST 2006


[Switching to haskell-cafe]

Niklas Broberg wrote:
> Ehum, shameless plug. :)
> 

Pretty much what I was fishing for...

> On 3/6/06, Graham Klyne <GK at ninebynine.org> wrote:
>> Cale Gibbard wrote:
>>> Ah, neat, I knew about WASH, but somehow I'd missed the fact that
>>> there was a server there :)
>> Interesting... at a casual glance, this looks as if it could be coming close to
>> being a "full stack web application framework" for Haskell, looking to occupy
>> the same kind of territory as systems like Java/Servlets+JSP+the rest,
>> Ruby/Rails or Python/Turbogears (the last a package I'm currently using).
> 
> Have you looked at HSP [1]? This is exactly what the HSP project aims
> for, although there is quite some ways to go yet.

I've noticed it, but haven't yet taken a closer look.  Currently, I'm pretty
busy with non-Haskell activities, but I'd love to find a sufficiently mature
tool to migrate some of my work to Haskell.

>> I think see:
>>   The web server
>>   CGI process dispatching
>>   Web page templating
>>   Relational database access
> 
> All of these are present in HSP.

I noticed that WASH makes some mention of HSP.  My main concern with a *SP
approach, and a reason I haven't delved more deeply, is that they are, AFAICT,
heavily dependent on code embedded in HTML, when I really want to separate the
code and markup as much as possible.

>> Additional features of a full-stack web application framework that may or may
>> not be present are:
>>
>> - Support for longer-running web processes (implemented in haskell, of course)
> 
> HSP has that.

Ah, OK... I wasn't aware of that.

>> - An easy way to map incoming URIs to specific functions (hmm.. or to monadic
>> values, I think)
> 
> I don't think I understand what you're after exactly, but I'm sure
> it's interesting, care to explain a bit further? :-)

I'll try and explain using Turbogears as example.  Actually, I think that
Turbogears would make a good model for building a Haskell Web application
framework, since many of the key integration points are implemented using higher
order functions.  It makes heavy use of Python 2.4 "decorators", which are a
(constrained) form of functional composition for class member functions.

The web server/controller component of Turbogears is CherryPy.  Roughly, a class
maps to a web server "directory" in URI space, with a declared class
(conventionally "root") corresponding to path / for a server.   Member variables
use used to create subdirectories.  here's an example from soemthign I'm working on:

[[
class Root(controllers.Root):

    panel    = PanelRenderer()		### Note 1
    webbrick = WebBrickAccess()
    itunes   = ITunesAccess()

    @turbogears.expose(html="templates.welcome")	### Note 2
    def index(self):
        return dict(now=time.ctime())

    @turbogears.expose(html="templates.listpanels")	### Note 2
    def panels(self):
        def selectPanelName((_,nam)):
            return nam[:-4]
        pattern = re.compile( r'^.+\.xml$' )
        c = CollectFiles("../resources/paneldef/",pattern,recursive=False)
        return { 'baseuri' : turbogears.url("/")+"panel/", 	### Note 3
                 'panels'  : map(selectPanelName,c) }
]]

Notes:

1. These assignments create sub-pages of the root page for http://.../panel/,
http://.../webbrick/, http://.../itunes/.

2. This is the Python decorator syntax, that defines a class method as a
composition of the decorator function (turbogears.expose) and the function
definition that follows.  The turbogears.expose decorator performs two functions
here:  (a) it causes the function to be exposed as a web page; e.g.
http://.../index or http://.../panels, (b) it uses the output from the defined
function as input to a templating system to format and return an HTML web page.

3. The templating system uses a Python "dictionary" type to accept values that
are included in the constructed web page.  You will note that this code is
completely independent of the details of the templating syst actually used.
Indeed, Turbogears can be used with more than one templating system, and (in
principle), I think the decorator system would allow miore than one such system
to be used within a single application - not that I advocate this ;).

I think all of this could be converted quite easily to appropriate Haskell idioms.

>> - Easy mapping from Haskell data structures to underlying SQL - what would be
>> called an Object-Relational Mapper (ORM) in OO languages
> 
> Some of our students are working on bringing the power of Ruby/Rails
> to HSP, with emphasis on smooth database interfacing. Not sure exactly
> what this entails though, I've never used Rails... :-)

IMO, Rails suffers in this respect by being too-tightly integrated with its ORM
system.  It's fine if you want, as Bruce Tate says, to "babysit a relational
database".  By in my application, I actually want to "babysit" a collection of
web-connected devices.

Turbogears, by contrast, leaves the controller/model interface completely in the
open:  there is no presumtpion that the supplied ORM code will be used.  This
means I can simply call my own (web client library) code instead of the ORM
code, and everything just works.  With rails, on brief examination, I felt that
IK wpould need to unpick the ORM interface and then implement my own "model"
code behind that interface -- just the kind of complexification and dependency
I'm trying to get away from.

>> - Handling of interaction with a browser-side Javascript library for smoother
>> AJAX support
> 
> This is not currently present in HSP, but they are surely on the
> conceptual todo-list. There is a design for a crude JavaScript
> support, but we'd certainly need more.

In turbogears, this mostly amounts to validation of form results coming back
from Ajax-enabled forms, as far as I can tell.  It's not a feature I've used yet.

BTW, the Mochikit Ajax library (component of Turbogears) is an interesting
example of functional idioms used in Javascript.

>> - Options to run the whole thing behind Apache to leverage its security and web
>> space management capabilities
> 
> Lemmih has implemented a HSP/FastCGI binding for Apache. I also know
> that work is being done on building a direct HSP/Apache binding. All
> work in progress though.

Yes, I was aware of a fastCGI for Haskell.  Didn't Bjorn Bringert (also)
implement one?  I tend to think of CGI programs as run-to-completion-then-exit,
even when a fastCGI interface allows a persistent wrapper program to speed
startup.  But I could easily be missing something here.

>> I think that continuation-based web session state management, ala
>> Smalltalk/Seaside, would be a very natural fit for a Haskell framework -- all
>> handled by a "Web session monad", maybe.  (Or maybe I just don't know what I'm
>> talking about ;)
> 
> This is by far the biggest drawback of HSP today. There is no
> high-level support for continuations (other than explicitly defined
> continuations at top level).

This is something that I assume would not necessarily be (too) tightly
integrated into the rest of the framework.  This is only a very vague sketch,
and I might be talking rubbish as I haven't studied this are in any depth, but I
imagine using something a monad to maintain the state of a web session, with
each incoming request corresponding to a bind operation, updating the session
state and returning a value to the client.  I'm not sure how closely this
follows technically the idea of using continuations, but I think the end result
is similar:  cleaner and well-isolated management of session state and web
transaction progress.

>> How far are we from having such a framework for Haskell?
> 
> Depends on how many people would be willing to invest time in it.
> Right now we have students at Chalmers working on a project that aims
> towards such a framework, but they can only do so much in the time
> they have. We would surely welcome any help we could get. :-)

Well, it's the sort of project I'd love to work on, but right now I also lack
time.  I've felt for a long time that Haskell would be a great language for
building Web applications, and my work with Turbogears is showing me how it
might actually all come together.  Part of the problem is finding someone who is
prepared to sponsor such work, as I've already taken a year or so working on my
own projects, and not ready to take the financial hit again.

> (ps. Going on vacation for 2 weeks in a few hours, so I'm not likely
> to respond for a while... ;-))

Have fun!

#g
--

PS:  I just spotted this in HWN:

[[
     * Haskell as a markup language. Oleg Kiselyov [4]writes on using
       Haskell to represent semi-structured documents and the rules of
       their processing. [5]SXML is embedded directly in Haskell, with an
       open and extensible set of `tags'. The benefit of this is of
       course in static type guarantees, such as prohibiting an H1
       element to appear in the character content of other elements.

   4. http://www.haskell.org/pipermail/haskell/2006-March/017656.html
   5. http://ssax.sourceforge.net
]]

I think this really should be in the toolkit, possibly at the heart of the
templating system.   I think this kind of capability is exactly why Haskell
could be so good as a web application language.


-- 
Graham Klyne
For email:
http://www.ninebynine.org/#Contact




More information about the Haskell-Cafe mailing list