Wow, definitely something I am going to check out. From a quick look, it seems that your Lisp code for the example looks a lot like HTML itself. For example:
(defun blogpage (&optional (posts *posts*))
(html-frame
"Restas Blogdemo"
(<:div
(<:a :href (genurl 'add) "Add a blog post")
(<:hr)
(render-posts posts))))
I don't know much about functional programming though, so sorry if that's an incorrect assumption.
Most of the Lisp web frameworks look like that, taking advantage of Lisp's flexible syntax.
Here's a Racket example. If you download http://racket-lang.org, you can just run this (no extra libraries or anything) and a browser window will pop up for you.
#lang web-server/insta
;; A "hello world" web server
(define (start request)
(response/xexpr
'(html
(body (h1 "Hello, world!")
(a ([href "http://google.com"]) "Google")
(br)
"I hope you like my site!"))))
This example renders as:
<html><body><h1>Hello, world!</h1><a href="http://google.com>Google</a><br />I hope you like my site!</body></html>
I need help understanding one thing. This code generates HTML code. Fine. But how come code and declaration (web designer and developer) are separated with this. Is this a good practice? I've been reading about lisp for a long time, not in depth, but I keep stumbling similar snippets a lot. Are there any good examples out there? I am teaching myself Clojure (reading the book with the bird cover) these days.
They are not separated. This approach appeals to geeks/programmers, but is completely impractical, as I've learned the hard way in several projects.
In a practical setting you will get a set of pre-cut HTML/CSS and images. Good luck splitting that into semantic markup and styling. And good luck teaching a designer how to work with it afterwards.
Because of hard-earned experience I try very hard not to put any HTML into my code, keeping it all in templates, which are much more accessible to designers and easier to modify.
Yes, this is exactly why I stayed away from things like this, despite my love for Racket and Clojure, until someone above pointed out the Enlive library. It lets you use normal HTML files as your templates but requires no code in it (not even for loops!) Basically, you use CSS-style selectors to replace the contents of elements, giving you the full power of Clojure but without having to either put code in your templates or put HTML into your code.
I have decided to investigate the possibility to include a sub-chapter to chapter 3 to discuss Caramel for people who like enlive(me included). I didn't already do so because caramel is brand new, and I haven't had the time to try it out beyond a few simple examples.
The choice to use s-expressions was made because It makes it easier to just type code in a repl and experiment, without having to worry about dealing with templates, and also because I wanted the first example to fit in a single file.
Oh, I was addressing the Racket example and the response to it, as opposed to your book; I'm not familiar with what you are doing in the book. I am still going to look into your book, as I have no CL experience, only Racket/Clojure. But adding a sub-chapter on Caramel would be really nice!
It's not as fancy as enlive though (for example, because it's not sensitive to the structure of XML, user input isn't escaped automatically, which is quite an awkward tradeoff)
That's a great text templating engine, but how does it handle the structure of HTML? Though our lisp solutions might be uglier than that, they:
- Are guaranteed to automatically produce perfect, valid HTML (or XML in my case),
- Automatically escape user-supplied input
- Make it very easy to generate lots of repetitive elements, or conditional elements, like other template languages.
Maybe I'm misunderstanding the spirit of your post? It seems like thinatra excels at the "routing requests from varying URLs" part, which solves a slightly different problem than the code we posted (racket for example provides a default path of http://localhost:40986/servlets/standalone.rkt -- definitely not what you would want)
Functions starting with <: are generated by the sexml library for outputting xml and html from lisp expressions. There are many similar libraries in pretty much every lisp dialect.
Is there any Django/Jinja-like templating engine for CL or Clojure?
...this way or the Clojure Hiccup way is cool for an ubergeek doing full-stack development, but in the real world you'll want your HTML templates separate and in a designer or front-end-coder friendly format. Otherwise, you may have the full power of Lisp at your fingertips, but you'll need to have your entire team used to this workflow and knowledgeable of Lisp, and by having logic in templates and such you're dangerously close to leaning towards the "PHP way".
...the only realistic "homogenous" solution for one language on the server and the client are the Javascript based way, in the Node ecosystem. Good designers or good front-end guys in general will also have coding skills, some will be Javascript gurus, but by doing things this way and writing Javascript code in Parenscript/Clojure script you'll have to force them to learn Lisp in order to work at 100%. And my bet is that they're not gonna like it, so team-wise, you'll lose all the productivity increase you gain in the first place by using Lisp.
IF you can find a team of lispers that also have webdesign and frontend coding skills, great, but this will be fucking hard as far as I know it. I would just love working in such an environment, but it seems like a non-existent Nirvana right now...
It also compiles to js, so you can even share templates between the client and the backend.
I'm experimenting with using both sexml and closure-template, but in the book I use almost exclusively sexml to make the code simpler. Also s-expressions are much easier to type in than sgml :)
Great! When you're done with this, can you be persuaded to write one about Weblocks?
I'm kidding, but not entirely. Weblocks is an extremely powerful and sophisticated framework, but it has a bit of a learning curve. It desperately needs a good tutorial.
In general if you prefer FP, clojure is a great choice. If you like multi-paradigm, and mixing up OO with FP, and procedural as you see fit, go with CL. I'm a multi-paradigm kind of guy, but clojure remains my second favorite language :)
An incredible coincidence -- I was starting to look into common lisp web programming just this morning, for a personal project. Do you have any estimate on when the book will be finished?