Introduction
I’ve been following the Weblocks web framework for about a year now, and it’s my opinion that Weblocks is the best Common Lisp web framework available. One of the difficulties with Weblocks right now is a lack of documentation and example code. This will be a contribution to that need. I have created a simple blog application based on Weblocks. I started with the blog that Evan Monroig put together as a simple tutorial, but wanted to go a little further with it. This will be a multi-part screencast tutorial, but rather than spreading it across multiple posts, I”ll just update this one as I have new material to post. I apologize in advance if there are very dry moments in these videos; I’m new to screencasting and am using free tools. You get what you pay for
So let’s start…
Setup
I use the Linux-Emacs-Slime-SBCL stack for the screencasts. Slime, Emacs, and SBCL are functional on Windows, but I don’t know that Weblocks (or, more importantly, it’s dependencies) will. I haven’t tried. I prefer Franz’ Allegro Common Lisp, but Weblocks is targeted specifically at the Hunchentoot webserver. There is a very good Lisp environment screencast by Marco Berringer, and an accompanying reference by Peter Christensen. I highly recommend them for learning more about how to get your Lisp environment set up. There are many other references on the web that will help you with getting Lisp set up on your machine. I use the Gentoo distribution of Linux. Gentoo has a very good package management system called “Portage”, which works something like the FreeBSD/OpenBSD ports system, but better (there are also drop-in replacement systems that improve on Portage in different ways, but I haven’t had a need for them; Portage works just fine for me). One of the more recently developed features of Portage is the concept of “overlays”, which provide the ability to more easily customize the set of packages available at a particular location or over a particular subset of categories. There is a Common Lisp overlay that provides fairly up-to-date releases of most of the useful Common Lisp libraries available (the overlay contains 200+ ebuilds), and I’ve found that to be adequate for my needs. Thus I avoid all the teeth-gnashing over Lisp library management and installation. For me, I just needed to install Emacs, Slime, paredit, SBCL and finally Weblocks (which pulls in a lot of other libraries as dependencies) through the portage system. The only thing I needed to do to make things work was to edit my .emacs and .swank.lisp files. My .emacs file needed this:
(load "/usr/share/emacs/site-lisp/site-gentoo" nil t)
and my .swank.lisp (the user lisp initialization file for swank, the Slime backend).
(defun project-setup () (mapcar #'(lambda (path) (push path asdf:*central-registry*)) '( #p"/home/bc/proj/weblocks-dev-aggieben/" #p"/home/bc/proj/simple-blog/" ))) (project-setup)
As you can tell (hopefully), the PROJECT-SETUP function merely adds my local project directories to the ASDF path so I can simply use (require :simple-blog) to load my application (SBCL’s REQUIRE function uses ASDF to find packages). The two directories I’m adding to the ASDF path are key to this tutorial: I am a Weblocks contributor (barely), so I run a local development version of Weblocks in my project directory. Most users can just install Weblocks however is best supported by their Linux distribution, through ASDF-INSTALL, or manually. This tutorial was created and tested on the latest development version. It may or may not work on the last stable (0.8, I think). Also, I added the ’simple-blog’ directory to the list because that’s where we will create our application.
Creating a Weblocks Application
After making sure my Lisp environment is set up, I can start everything up:
At this point, we have the skeleton of a Weblocks application. It only writes a little text on the site, but all the plumbing is in place. Since we’re building a blog, we need to design a simple object model to represent it:
Now we have our object model in place and have shown how to use gridedits and default views for viewing and data entry, as well as the limits of the default views. In order to successfully input data, we need to customize the form views:
Now that we have data entry working, we need to build more interesting pieces of our blog. Firstly, how do we display a post to a user? We can write a custom widget to do that:
We’d like to be able to show more than one post to a user. We’ll construct a custom widget to represent the blog itself:
Check back for updates….when I get time, I’ll post screencasts to demonstrate further improvements to the blog, including graphical styling, navigation, author login, and tags.
I’ve been trying to write a web application in my free time. It’s been going on at varying degrees of intensity for months now, and I’ve got virtually nothing to show for it. Part of that is due to a lack of time to devote to it; at best, I can add 2 hours to the top of my day by getting up early.
But the point of the post is really the other compounding factors that the various technologies impose on me, and how that relates to the client perspective in typical contracted software work.
My day job involves almost exclusively Microsoft technology; .NET in particular. We use Sharepoint to build client intranet applications, do custom C# development, etc.
In my hobby projects, I tend to play on a Linux platform with Lisp or C++ (although I certainly am no stranger to the Windows platform or other languages). The webapp I’m working on has been based on Weblocks, a continuations-based web framework for Common Lisp. I have an idea of what I want it to be and do, but Weblocks isn’t well documented and I’m not very experienced with it yet, so I come to it asking this question:
what can I do?
The framework is also pretty liberal, so even once I know what it provides, I still have the same question because the possibilities are limitless. In a way, this expanse is paralyzing: I have to spend a lot of cognitive energy figuring out among the zillion design choices at each step, in addition to learning a technology I’m inexperienced with. Consequently, it takes a really long time to get something working. However, once it starts to roll, it can roll fast because once I’ve made my design decisions and worked out my requirements (informal as they may be), I understand where I’m going and generally how to get there.
I have another hobby project, a Git client for Windows built in WPF and C#. With that project, I ask a different question:
How do I do that?
This is because of the nature of the platform. True of closed, proprietary platforms in general, but in particular of comprehensive frameworks like .NET, most of the design decisions have already been made. I don’t have to choose among the zillion ways to render a components in HTML/CSS/Javascript and process user activity – there’s already a mechanism just for that in ASP.NET called “web parts”. I don’t have to make a hundred design decisions about the desktop GUI framework to use and how to use it or roll my own or extend one, etc, because the Visual Studio and Blend designers support WPF. With this platform stack, the tradeoffs are reversed: I can get rolling on a project almost immediately, but at some point, things get really hard because of the box you find yourself in down the road (and at least part of the box is hidden from you because of the proprietary nature of the stack – the Sharepoint object model is a perfect example because it sucks). I once worked on a system that had it’s own threadpool because the .NET threadpool didn’t perform well enough, for example. That was not a quick project.
What struck me about this contrast was that I found myself empathizing with the position of a client.
As in the first case, the possibilities are endless – unmanageable – at first, and I didn’t know what I wanted, and nobody was there to tell me – but later on, the freedom in those design choices was favorable.
In the other case, I had some very concrete ideas about what I wanted because the technology limited my choices, but those limitations created pain points later on because they became very confining.
Conclusion? I don’t know, really. Each position has it’s advantages and drawbacks. I tend toward the former as a craftsman, but toward the latter as a consultant for a variety of reasons, including market inertia.
Tags: business, consulting, programming
By training and experience, I’m largely an object-oriented programmer. I was a freshman comp. sci. student when the Java wave hit my university, so that’s what I was fed. I didn’t learn anything else but Java until the summer after my sophomore year; then, I was involved in a summer research program for which I used C++. Between then and the end of my undergraduate tenure, I had picked up more C++ and learned C (I should add here that my department was and is a very good c.s. department – they just didn’t use functional languages as teaching tools).
Where did that leave me? I knew how to write nice object hierarchies, tight structural/procedural code. However, Boost wasn’t a big deal yet, and I had only barely dabbled in anything else, so I was missing a huge piece of the puzzle: functional programming. I used lisp for a couple of programming assignments in graduate school because I wanted to learn the language – and I did learn the basics, but what I didn’t learn was important functional concepts.
Now, as a working professional programmer, I’m still trying to learn functional concepts. Some are pretty easy: immutability and recursive computation. These are very basic – even recursive functions were taught in Java programming classes.
But the most interesting element of functional programming is higher order functions, which are the basis for some very powerful forms of abstraction. This is what I was really missing in my repertoire.
So now, the point: I’ve been trying to learn a web framework called Weblocks. It’s freaking cool – but it makes heavy use of continuations for control flow (one of its major features). I had never learned about continuations before, so this was (and still is, to some degree) making it hard to learn the framework. So I was reading about continuations online (here ,here, and here) and came across a reference to Paul Graham’s book, On Lisp. I have a copy that I printed for myself, so I looked up the chapter on Continuations to gain some insight, and found the best explanation I’ve seen so far:
A continuation is a function representing the future of a computation. Whenever an expression is evaluated, something is waiting for the value it will return. For example, in
(/ (- x 1) 2)when (- x 1) is evaluated, the outer / expression is waiting for the value, and something else is waiting for its value, and so on and so on, all the way back to the toplevel…
We can think of the continuation at any given time as a function of one argument. If the previous expression were typed into the toplevel, then when the subexpression (- x 1) was evaluated, the continuation would be:
(lambda (val) (/ val 2))That is, the remainder of the computation could be duplicated by calling this function on the return value.
I found the little example shown here to be the best way try to explain continuations. Trying to understand the applications of continuations is a beast, and without this basic understanding it’s very easy to get lost.
Now…back to Weblocks…
Tags: functional programming, Lisp, programming