Fog Creek Software
Discussion Board




An HTML Carol

Like all carols it's too long and slightly annoying, but since we're on the subject of singing HTML ...

There's this thing that I've been working on for quite a while.  It's a web server and an environment for web applications (I know, I can hear you all saying, "it's been done!").

But this environment is built to make it easier to create a certain kind of web application: traditional event-driven GUI apps.  Yes yes, to some extent this has been done too (I hear that ASP.NET does this to some degree but I haven't really used it -- though I've done quite a bit with the old ASP), but I think that I might have a few interesting things to say about it.

The language that this programming environment knows about is this Scheme-like thing that I put together.  But really it's easiest to think about it as the underlying semantic model and not necessarily the language that should be used to represent these applications in a production environment (I've got my own parser generator and tree-munger to conform other syntaxes to this model anyway).

So here's how a source file might look (semantically if not syntactically):

(tree 'MyTree width height node-generator child-generator click-function)

(button 'MyButton width height (lambda () ((MyTree 'addnode) (MyTree 'selectednode)))

This creates a tree control and a button control on a web page (with their specified widths and heights).  The tree also has some functions associated with it (node-generator, child-generator, click-function) but let's ignore those for now.  The point here is that with this declaration you get two controls available to you.

The lambda function provided to "button" represents the stuff that happens when somebody clicks on the button.  We'd like that function to have the states of all controls available to it, and to change the states of those controls as well (just like you do in a regular event-driven app).  The first part of this little trick is simple enough: you just output a set of JavaScript "function pointers" associated with property names (an array of code that can be evaluated to get the corresponding property).  Then the implementation of controls that raise events can analyze the function you've provided to handle events, and it can output a bit of JavaScript code to only poll those functions in the property map which are referenced in the event function (before ultimately packaging up this set of properties and making a call to the server to invoke the aforementioned event function).

Changing control state is even easier, since it essentially involves generating some JavaScript calls to ask the HTML representation of those controls to do something (e.g.: add a node to a tree, select a range of cells, animate a barking dog, etc).

So once you've got this basic plumbing in place, it's easy to implement some basic controls and get a really powerful system in place for building web applications.  Oh yes there are more fiddly details to work out, like using hidden iframes/objects to make the RPC calls necessary to invoke these events, but that's easy to hide behind this system too (Joel's "Law of Leaky Abstractions" notwithstanding).

What's left?  Well you have to have some way of keeping track of these event functions between connections to your web server.  For the server I made, I added a "load" and a "store" function to the script environment.  "store" would save any value forever (and return an ID for getting that value back) and "load" would get back the value saved by "store" ( (load (store x)) = x ).  So I can store the function associated with an event and pass that ID to the RPC iframe/object that will wind up invoking it.  This reduces the problem to the same one of passing control state to the event handler (and it means that you can easily change control event handlers on the fly too).

On a side note, because this dialect of Lisp supports lexical closures, values defined outside of the event-handler function are visible to it, so if you want to have some global variable that gets decremented every time somebody clicks a button, you can trivially do that too.

At this point, maybe you're saying to yourself, "who cares?"  I don't have a very good answer to that, but hey we're software developers and we're used to soul-crushing Sisyphean tasks (whether we push the rock for the full 8 hours or we're muppet).

Anyway!

Looking at those two really simple lines of code there, I keep thinking that a Visual-Basic-like application for this sort of thing would be useful to a number of people (especially if the server end ran on cheap commodity hardware/software).  It's easy to derive a desktop interface from the code too (I've done this for the simple case of the basic collection of controls described above).

Is this interesting to anybody?

Kalani
Wednesday, August 04, 2004

I think people who try to force web based applications to do the event-driven thing are funny.

It smacks of "I can't cope with this technology so I'm going to twist and knot it until it behaves similiarly to this other technology that it's completely unsuited to imitate."

It's like buying a dog for lack of a cat and then forcing it to meow and hunch over so as not to be so tall.

muppet
Wednesday, August 04, 2004

Wow.

If I give you some money, can you get some for me and my friends?

Off to look at the stars tonight
Wednesday, August 04, 2004

I don't think that's really fair.  I certainly *can* cope with the way that the web works, and I've done so in many instances.  I've written tons of "traditional" web apps (like your web forum, or a book self-publishing system with a web interface), as well as developing (or redeveloping) plenty of net/web infrastructure stuff like TCP/IP implementations and web servers/script-interpreters.

But let's say that you want to search something on your work machine while you're at home (actually muppet, this is a perfect hypothetical situation for you since you do so much work at home), and as part of that process you've got to pick a directory as the root for the search.  Well what's the best way to pick that directory?  I think that something like the Windows browse-for-folder dialog is very close to that.  A system like the one I've described makes it trivial to implement a dialog like that one (I've got an example of this if you care to see it).

Sure, it's really silly for a large number of different types of applications.  On the other hand, it's very very handy for several others.  You can say the same thing about traditional web programming.  But this is one model within which web development might expand to meet ever more complex requirements for certain applications (only because it's so easy on the implementor).

Kalani
Wednesday, August 04, 2004

There may be some very good reasons to do what you're trying to do, but it'd be worth it to spend some time seeing what else is out there, so you don't reinvent the wheel or produce a product that has no market.  If something out there meets your needs, you can go ahead and use that.  If there's nothing out there that you want, you'll at least have an idea of what not to do in your project.

Off the top of my head, you definitely want to look at ASP.NET (go to www.asp.net and download the free WebMatrix IDE) and IntraWeb from AToZed Software.  There's probably also some PHP/Perl/(some other *nix thing I don't know about) product that does similar things and should be checked out.

Kevin
Thursday, August 05, 2004

That's interesting.  I'd seen a bit of the ASP.NET stuff before but the program you mentioned is great.

It's still not quite what I had in mind.  Invoking an event results in the whole page being updated, and all of the states of all of the controls get posted.  Plus there's still a division between web applications and regular desktop applications.  I'd like to take the same code and either compile it to a desktop app or compile it to a web app.

This IntraWeb thing from atozed.com is close to what I had in mind (the interface editor looks great), but it seems like it's still the full-page post.  I'll look at it a bit more.

Kalani
Thursday, August 05, 2004

You can write a .Net WinForms project and deploy it over the web, although this requires the .Net runtime on the client.

You should also look at Mozilla's XUL technology, which enables some similar things but requires a Mozilla browser.

With all that said, your project sounds like it would fill a niche that's not really filled currently.  Whether people really need a method for web apps that minimize postbacks is another question, but I could see it being useful in certain situations, at least.

Kevin
Thursday, August 05, 2004

*  Recent Topics

*  Fog Creek Home