June 12, 2002
Lisp Server Pages

Let's get a little codey.

A long time ago, the company I worked for went from doing research for NASA on natural language interfaces for complex systems to making web sites for truckers. I ended up doing a lot of web programming, some with Java Server Pages (JSP). More recently, at i/net, I experimented with using JSP-style techniques with Lisp--Lisp Server Pages.

Lots of people write their own version of LSP. It's kind of fun to implement, and a basic version is like a page of code so it only takes an hour or so. I just figured I'd save you a little time up front.

The code has been generously made available by i/net under the MIT license. You can download it as a tarball. It's generic lisp and should run in any lisp that AllegroServe supports. (I get annoyed when I have to go through the whole process of downloading and untarring something before I can look at the source and get an idea of how good or bad the code is. So here's the source, straight up.)

You can see it in action in this short example: example (source), which is backed by OpenMCL and Portable AllegroServe. I'm sure that 500 years after the fall of man, when humans are reduced to huddling for warmth inside the ruins of Sony Style stores while staying alert for the quiet skittering sounds that mean they've been discovered by a pack of intelligent (and angry) GM guinea pigs in their sharp-legged, flame-throwing arachnid exoskeletons, that these example LSP pages will continue handling requests from whatever hosts remain forgotten on the internet, not caring whether the human race wins the long battle to reclaim their place as dominant species, power LEDs slowly blinking out one by one as capacitors fail (seems like it's always the capacitors) and the once profound symbols of modern technology go silent.

Or I'll restart the machine and forget to start OpenMCL too.

Anyway, the experiment more or less failed. I began to suspect the reasons behind JSP's ugly appearance had less to do with Java than with the crazy idea of mushing two unrelated languages and syntaxes together.

So here's some documentation. It's quite a lot for such a small amount of code, but indulge me.


Java Server Pages are a way to make web pages that are dynamic, by embedding Java code in HTML. Similarly, Lisp Server Pages allow you to make dynamic web pages that contain Lisp code.

To publish an LSP page, call the publish-lsp function:

publish-lsp (&key path filespec server) [function]
Publishes the LSP file filespec at the URL prefix path, on server defaults to the default AllegroServe server, *wserver*). Example: (publish-lsp :path "/temp.html" :file "/Users/wiseman/src/temperature.lsp")

An LSP file looks just like an HTML file, except for two new tags: <% ... %> and <%= ... %>.

<% ... %> is a scriptlet tag (to use the JSP terminology), and wraps lisp code. For example, <% (dotimes (i 10) (beep)) %>. The code inside the tag is executed each time the page is requested.

<%= ... %> is an expression tag, and the effect of this tag is to evaluate the contents as if they were wrapped with the Franz net.html.generator:html macro. For example,

<%= (:h1 "header") "hi" (:princ-safe (generate-footer)) %>

is equivalent to

  (:h1 "header")
  (:princ-safe (generate-footer)))

which will output something like the following HTML:


During execution of LSP code, the following two variables will be bound:

The HTTP request object containing all the information about the request.
The information passed to the publish-lsp function.

(See the AllegroServe documentation for more information on these objects.)


Expressions can be used inside HTML attributes, e.g.,

<img src="<%= (img-title request) %>">

Scriptlets do not need to be complete lisp forms, as long as the page as a whole is syntactically valid, e.g.,

<% (dotimes (i 10) %>
  <img src="mr-yuck.jpg">
<% ) %>

Implementation Notes and Caveats

LSP pages are converted to strings containing lisp code, which are then compiled and cached. If the source file containing the lsp code is modified, the next time a request is made for that page the code will be recompiled and recached.

In my first attempt to do this, I tried to construct forms instead of strings. That just made it trickier to separate forms across <% ... %> tags (see the dotimes example above). Just because it's bad that other languages are often limited to manipulating code as strings doesn't mean there aren't times where it's appropriate.

There's nothing like JSP's directives or declarations.

LSP Requires Franz' AllegroServe (http://allegroserve.sourceforge.net/) or Portable AllegroServe (http://portableaserve.sourceforge.net/).

See http://sourceforge.net/projects/lsp for a more serious attempt at doing this right, by Sunil Mishra and Tim Bradshaw.


Would have been a lot cooler in 1997.

Posted by jjwiseman at June 12, 2002 12:03 AM

If you spell it LiSP, then it's almost a recursive acronym.

Posted by: Jim on June 13, 2002 08:56 AM

"the company I worked for went from doing research for NASA on natural language interfaces for complex systems to making web sites for truckers."

Heh. "Funny cause it's true." But *so* aptly stated.

Actually John your comment about the disparate syntaxes is right on the mark. IMHO jsp always kind-of-sucked because the code looked so ugly. Especially when you throw in some javascript.

Posted by: bill milbratz on June 19, 2002 08:43 PM


Posted by: ng on December 15, 2002 10:14 PM


Posted by: kkkkk on February 28, 2004 01:43 AM

"Lots of people write their own version of LSP. It's kind of fun to implement, and a basic version is like a page of code so it only takes an hour or so. I just figured I'd save you a little time up front."

Yeah, thanks! :-)

I used the code for CL-EMB: http://www.cliki.net/CL-EMB

Posted by: Stefan Scholl on August 13, 2004 10:47 AM

JSP needs to use tag libraries and JavaServerFaces to be written in anything like maintainable style. Of course, java will still suck, but you will be multiplying that less.

Posted by: Marcin on August 20, 2004 05:04 AM

That's why CL-EMB somewhat combines the features of LSP and HTML-TEMPLATE.

Use it for easy templates. If you really need more you can embed Common Lisp. But the current version is 0.0.3. Who knows what the future will bring?

Use it as the main framework for rendering HTML, or just as a tool for some easy stuff. Or don't use it at all. You can embed some of the Lisp Markup Languages (e. g. CL-WHO, LML2) withing the CL code. Or the other way round: Use LML2 for all but a small part, which gets included via a call to a CL-EMB template.

Tell your HTML designer to just put a "<% @include navigation.tmpl %>" where he wants to see the navigation. And inside navigation.tmpl you make your calls to a DB, or whatever you need to build the navigation.

Posted by: Stefan Scholl on August 20, 2004 05:25 PM
Post a comment

Email Address:


Unless you answer this question, your comment will be classified as spam and will not be posted.
(I'll give you a hint: the answer is “lisp”.)


Remember info?