
Ask HN: Common Lisp vs Clojure for web apps? - hackoder
I'm building a somewhat complex web app, but eventually what I need are 1) support for postgres, 2) libraries which make it easy to deal with data in json and xml, and 3) allow me to generate html and javascript.<p>Overall, I think both CL and clojure support this basic feature set. And I'm trying them both out on a trial app anyway to get a feel for them.<p>However, I'd appreciate if anyone can provide me with some tips/guidance/gotchas/"this might help" sort of advice to get me going. Thanks :)
======
tumult
Either will allow you to do this. I imagine the only difference (in terms of
existing features for your platform) would be 'generating JavaScript.'

CL has Parenscript <http://common-lisp.net/project/parenscript/> which is
probably more powerful than whatever JavaScript compiler/macro/generator tools
you would have to hack together yourself in Clojure.

As for my own personal opinion, I would choose the Lisp that has tail call
optimization.

If you are willing to look into a third option, I highly recommend HOP from
Inria <http://hop.inria.fr/> which is a Scheme web platform with a true
JavaScript compiler.

~~~
KirinDave
Parenscript, a javascript generator, eh?

I don't understand, why would anyone want to generate javascript from S-exprs?
I understand this is fashionable in the CL world, but I've never seen any good
justification for this practice outside of saying, "Now everything is in
lisp."

But this isn't a terribly compelling argument. Most web applications are
multi-language and it doesn't seem terribly detrimental to them. Further, the
state of the art in web technology moves so incredibly fast that it seems
strange and almost obstructionist to insist on a secondary library that needs
to be kept in synch.

Finally, it tends to lead to crap designs. Anyone who does cross-browser
implementations designs will tell you that simple CSS over a generic HTML
framework is almost never enough. Frequently you need to introduce new
enclosing scopes or add seemingly senseless markup to help make IE play nice
(a torturous exercise many web designers still need to go through). So while
CL has some awesome web libraries, I'd say their extensive work into making
HTML+JS+CSS generation from pure lisp seems like a foundation built on sand.
Sometimes I wonder if the whole exercise was just to avoid working with HTML,
which many (more prejudiced) developers find distasteful to work with.

I don't think Clojure is at a significant disadvantage to CL in this field. If
anything, it's at an advantage in web applications, as it has access to a
massive number of very good web-related and utility libraries. A paucity of
modern, battle tested libraries that "work everywhere" has always been Common
Lisp's achilles heel.

~~~
gruseom
You say you "don't understand", apparently disingenuously, because you then go
on to announce what the argument supposedly is, object to it, change the
subject (what, exactly, does Parenscript have to do with HTML?) and end with a
red herring.

As someone who works in Parenscript every day and hasn't had his coffee yet, I
find that irritating.

~~~
KirinDave
> (what, exactly, does Parenscript have to do with HTML?)

Because we frequently see Parenscript used in isolation from sexp->html
compilers? I sure don't.

I'm not ending with a red herring, I'm saying you're creating a huge
integration hassle with the rest of the web application world. Heck, even
pattern-substitution templating systems are falling out of style as it becomes
feasible to do structure-substitution templating. Most designers and
javascript experts do not know lisp, and further don't want the equivalent of
a wet blanket separating them from their medium.

And I don't mean to upset you, but I also notice that you didn't exactly
provide any justifications for parenscript. It's a cool project, and I've even
used it for production work. However, I never felt it was anything more than a
stopgap solution, and my impression from the CL community was that they didn't
like HTML+JS because it wasn't lisp.

~~~
sedachv
"I'm not ending with a red herring, I'm saying you're creating a huge
integration hassle with the rest of the web application world."

How so? You're still getting regular JavaScript out of Parenscript. That's the
whole point.

"Heck, even pattern-substitution templating systems are falling out of style
as it becomes feasible to do structure-substitution templating."

What is pattern vs structure substitution? I've never come across those terms.

------
prosa
On the Clojure side, definitely check out Compojure, a Sinatra-style
framework.

<http://github.com/weavejester/compojure>

------
nunb
> I'm building a somewhat complex web app

I'm guessing that if you had a CL background the choice would be easy!

The answer also depends in part on what your app structure's going to be
like.. some considerations:

A. Will you embed your UI logic in Lisp?

B. How interactive do you want your application to be?

C. How computationally intensive will it be?

D. Is horizontal scalability (ala swarmiji) important?

E. Will the application deal heavily with forms?

F. Do you want to use SQL, or go through an ORM? Or use objects directly? (eg
(mapcar #'do-foo (all 'clients)))

> make it easy to deal with data in json and xml, and

cl-json has been very easy to use, with trivial mapping from lisp objects to
json.

> allow me to generate html and javascript.

We use html-template. If you're using forms you'll have to decide where you
want to put your validation logic. With html-template you'll probably end up
rolling your own, or do it in javascript.

A big consideration may be that Clojure is much more strictly functional than
CL. That may limit your coding flexibility (and be harder to adjust to if you
come from an imperative-coding background).

IMHO going with CL will yield greater benefit with Slime and the debugger,
related to dynamically responding to requests, debugger-tested programming
etc.

Real-world Clojure programming seems to require a knowledge of java libraries.
CL libraries have been available for everything we've wanted to do. Postmodern
is probably faster, and more "native" than JDBC.

If you want to put your UI complexity in Lisp (as opposed to javascript) then
check out Weblocks, which has many nice features, one of which is generating
validations from the data-model. If you want to write a RESTy app then plain
hunchentoot should serve just as well.

Have you checked out some of the Clojure/CL webcasts? They should give you a
feel for the relative strengths and weaknesses of developing in both
environments.

------
wglb
Clojure seems likely to be able to plug into whatever Java libraries you might
want to use. CL (in particular, SBCL) is used to power a number of web sites
and they use Lisp all the way down. One of my favorites is
<http://wigflip.com/> that has a number of fun toys. Weblocks is a good CL
framework. and there is support for Posgtress (as well as mysql, etc etc)
available for CL.

Check those out for that side of what you can do with CL.

I am less familiar with the Java world, but Clojure seems to be very capable
in that area.

~~~
kunley
Last time I checked Weblocks it had an outdated documentation (as the original
author left the project) and new developers were adding new super-cool stuff
in such way that using it actually involved becoming a dev on the project.

Few years later I experienced the same with UCW (beign another continuation-
based web framework). And the same with Lisp-on-Lines (mr author, do you have
something working outside of your own lisp image yet, after 5 years or so?)

Then I came to conclusion that there's some reason in the CL world that many
projects become write-only vacuums with NIH syndrome, and their dev
communities don't care of creating a _user_ base as they favor having _dev_
base. Also the term 'change management' or 'release management' seems to be
incomprehensible by CL people. That causes almost impossible to deliver a
product to the customer based on such software and stay sane.

~~~
sedachv
UCW, Weblocks, and LoL were all started by people who did not understand web
programming. If you're using continuations to "abstract" away browser-server
interaction, you pretty much don't get web programming, period. Instead of
focusing on the browser, these people want to focus on the server and pretend
everything synchronously flows from there. This is a brittle and expensive
(esp if you don't have first-class continuations!) illusion.

That explains why the frameworks were not high-quality in the first place
(note: I personally don't believe that any web framework is worth using), and
more importantly why the people who started the projects left: they just don't
care about web programming (or actually any programming that has to deal with
asynchronous human input) and just wish it would go away.

Release management is a catch-22 in the Lisp community: until people who
maintain Free Software Lisp projects stop believing they don't have any users,
they won't invest in it, but until they start investing in it, they'll
continue to believe they have no users because people will just give up
instead of complaining about it.

~~~
kunley
Smart conclusions.

I'd add to the Lisp-vs-release-management problem: The "I live inside the
image" approach discourages delivering stable tested code changes, as it's
quite hard to isolate them. I agree using a REPL is great for prototyping, but
if one never builds from scratch, he can create the unmaintable code which
doesn't work outside of a few specially crafted and hacked Lisp images.

Luckily Clojure doesn't seem to hold this legacy. People usually seem to
inject code into the repl when they code but then switch to builds using ant,
maven or by some layer above them (see Leiningen). I do it as well, compile
inside a repl as it's quicker, then compile from scratch before a commit. It
seems to be a sane compromise. It's also good you can't save current "jvm
image" so there's no temptation to never leave it. I have a sad observation
that sticking to "live inside the image" actually produces lone-ego-superstar
programmers not willing to cooperate.

~~~
gruseom
I sadly agree that "lone-ego-superstar programmers not willing to cooperate"
are more prominent in the CL world than in some others. (Edit: "semi-autistic
pricks" is the term that comes to my mind. Still, many of us are not like
that.) I'm also willing to believe that the Clojure community is refreshingly
different in this respect. But I don't buy that "living inside the image" has
anything to do with this, or at least anything to do with causing it, and I
especially don't buy that a technical limitation of Clojure/JVM constitutes
some sort of virtue.

~~~
kunley
OTOH you can measure the technical limitation and then go around it in hours.
That's a lot easier than struggling against social limitation for years (as w/
CL).

------
pmjordan
I'm biased - I generally prefer the Clojure way of doing things to CL (data
structures, unicode, portability, library compatibility) but then the last
time I seriously used CL was ~2006-2007, so things may have changed since.

But, to address your requirements:

* JSON: clojure.contrib.json

* XML: clojure.contrib.prxml

I gather there are a JS generator and an SQL interfacing library in contrib as
well, though I haven't used them. Worst case you can access any Java libs for
those purposes.

You also get to plug into any webserver that supports Java servlets, if that's
an issue.

The killer feature for server programming in Clojure is the STM though. It
means you can multi-thread your server relatively worry-free without resorting
to moving all your state out-of-process (e.g. all state lives in the DB). You
still need to pay attention to synchronising I/O, but compared to manual
locking of _everything_ , STM is a piece of cake.

(context on my perspective: I've delivered a Clojure-powered back-end server
for a multiplayer Flash game for a customer, as well as made some minor short-
lived web sites; clojure was great for all of those use cases - I'd link to
them if I was allowed to put my name against them)

------
francoisdevlin
I say Clojure, because I would be hard pressed to think of a platform better
than the JVM. Garbage collection, speed, deployment are all top notch in java-
land.

Postgres support will probably be easier w/ Clojure, because everything is
writen in terms of JDBC. Postgres is also routinely integrated w/ clojure
apps.

Clojure supports xml parsing out of the box, and there are json abilities in
clojure-contrib.

------
smanek
It really depends on you (and I say this as someone who just chose to write a
huge CL webapp).

If you have experience with Java - I'd probably go with Clojure. If you have a
lot of background with Lisp (i.e., Slime/ASDF don't scare you) I'd go with CL.
If you don't know either - just pick what's more interesting to you (but be
aware there's a steep learning curve either way).

On the CL side of things:

-You want to use Hunchentoot as your webserver

-CL-SQL for persistence

-CL-WHO if you want sexp => HTML, or html-template if you want pure HTML templates

-Parenscript is good for Javascript since code you write in Parenscript can run on either the server or browser (it makes it really easy to Ajaxify things, for example). But, if you're doing lots of really fancy JS and you're great at the language already, I'd stick with pure Javascript.

-For JSON, I personally prefer YASON to cl-json, but take your pick (they're both fine).

~~~
tayssir
I preferred Postmodern last year, for interacting with Postgresql. Around that
time, I vaguely recall it was considered faster than CL-SQL as an Elephant
backend; and I found it far easier to install than CL-SQL. (I recall during
CL-SQL's installation, it kept signalling errors for each DB it supported
which I hadn't installed. Someone at the office said I was supposed to just
keep telling Slime to ignore the errors, prodding the install forward. That
actually worked.)

Maybe things have changed in the interim?

If the OP chooses Clojure, then I'd note that the Java classpath really
demands you respect its inflexibility. add-classpath is a second class
citizen; I've had JDBC (the Java DB manager) swear up and down that it
registered the MySQL driver I loaded via add-classpath. But come time to read
from the DB, it only worked when I ensured that the MySQL driver was loaded at
the beginning in the normal way. What that implies is that if I want to load a
new DB driver, I'd probably have to restart the JVM. (Or do something absurdly
tricky, or debug more deeply.)

~~~
JulianMorrison
I think your problem is more likely to be with class _loaders_ than class
_paths_. Clojure probably has to set up its own, to allow all the monkey
patching it does, including dynamically setting the classpath. If JDBC was
loaded already, it will be able to see Clojure objects passed as parameters,
but not able to find the class by reflection on its name.

------
mahmud
Both Clojure and CL can do those basic things, now which one do you know best?

This feature-based language choice is meaningless if you're not taking your
own strength into consideration.

------
nearestneighbor
Clojure is cleaner than CL, but SLIME does not appear to work as well with
Clojure as it does with CL. For example, if you have a compiler error, you
have to navigate to the location of the error yourself. If you have a runtime
error, you get a Java backtrace, that SLIME does not help you with at all
(good luck). This is something you should consider, because it will have an
effect on your development speed.

------
itistoday
I was in a similar situation: I love LISP and I wanted to use it for web
development. I spent several days looking at Clojure and Compojure for this
purpose but came to the conclusion that it was far too restrictive and
cumbersome for rapid web development.

Then I discovered the Dragonfly framework, a web framework for the newLISP
scripting language and became its co-author.

Advantages over Clojure/Compojure:

\- No need to switch web servers to Jetty/TomCat. (runs as cgi).

\- PHP-like development, no need to recompile/reload code.

\- Extremely dynamic and flexible routes.

\- Very fast and very low memory usage.

\- newLISP is an awesome language.

<http://www.rundragonfly.com/>

<http://www.newlisp.com>

Questions to the Dragonfly forum:

<http://www.newlispfanclub.alh.net/forum/viewforum.php?f=17>

It's still young and is being actively developed, but I think if you give it a
look over you'll find much to love about it.

