

[Ask HN]: Clojure - why the optimism? - morphir

What is the reason for Clojure creating this optimism within the lisp community?<p>Has it succeeded where other lisps have failed?<p>Or is it just the JVM that all the sudden makes it cool?<p>If other lisps never made it into mainstream, why would Clojure all the sudden nail it?
======
hga
Why Clojure looks like it might be the "future of Lisp" (to quote Dan Weinreb
(he said something to that effect in his ITA Google talk)):

As I noted in my earlier posting, many would say the Scheme language standard
is too small and Common Lisp too big; Clojure aims to be just right.

It's not particularly multi-paradigm; rather, it's determinately functional
and aimed at the multi-core/multi-thread "future" that's now arrived. It's
"secret sauce" is a data structure
(<http://en.wikipedia.org/wiki/Hash_array_mapped_trie>) that solves the
functional programming trivial update problem ("changing" one of the built in
sequence types is O(n), where n is a max of 32 and more like 5-6).

With the above immutable data as base, it provides a variety of methods to
manage multiple threads, e.g. STM (which has a much better chance of working
in a functional language than trying to bolt it onto an imperative one),
"agents" which are much like actors, but they can safely share (immutable)
data and so on.

It provides a general approach to lists, vectors, maps and sets and makes the
latter first class citizens. Rich Hickey took the opportunity to ... update
the syntax to heavily and appropriately use vectors (they are denoted by
square brackets) and many people like this (I don't :-).

It has a Common Lisp style macro system with as I understand it some extra
features that make it safer than Common Lisp's.

And the proof is in the pudding: it appeared out of the blue in 2007 and has
seen a lot of uptake. It is already being used in production systems (e.g.
Flightcaster).

For this old Lisp hand (1979), it provides hope I haven't felt for Lisp since
the mid-late '80s.

------
gruseom
Common Lisp has two strikes against it: it's old and its community is
dysfunctional. A lot of people attracted to the idea of Lisp, but repelled by
one or both of those attributes, have found a home in Clojure.

It's much too early to tell whether Clojure will prove a technical success in
the long run (let alone a worthy successor to CL, which, for all the things
people say they don't like about it, is one of the magnificent achievements of
computing).

~~~
hga
To continue to my favorite Lisp family prior to discovering Clojure (and who
knows, it still may end up being my favorite :-), Scheme:

Is less old and has a less dysfunctional community:

Like Clojure, the community took the opportunity to dispense with a variety of
old cruft that's still in Common Lisp. It has a couple of processes that push
the standard forward; the one for base language changes has been very slow
prior to R6RS, but even that moves a _lot_ faster than Common Lisp, which is
essentially stuck in amber.

Although the process that produced R6RS seems to have been largely rejected by
the community (as well as the product) ... so we'll see what the R7RS effort
comes up with.

Scheme implementations are less standardized that Common Lisp ones, and this
matters in some important ways, e.g. there's no accepted standard for modules
(packages/namespaces/whatever). Frequently it takes some effort to port code
between the different implementations because non-standardized features like
threads were used (which Common Lisp doesn't have a standard for either).

No one's ever figured out a widely accepted FFI for either, so Clojure wins
big there.

Many would say the Scheme language standard is too small and Common Lisp too
big; Clojure aims to be just right.

------
hga
" _If other lisps never made it into mainstream, why would Clojure all the
sudden nail it?_ "

Very good question; here are my guesses:

We are exiting a Dark Age when the use of non-mainstream languages was nearly
impossible (I suspect this has to do with the dot com bust: companies just
don't have the money they used to have to throw at "safe" mainstream choices).

I strongly suspect PG's success story and thorough explanations of why Lisp
wins made more people willing to give Lisps a chance.

The more varied syntax (e.g. heavy and appropriate use of vectors which are
denoted by square brackets) finds favor with a lot of people who think LISP
stands for Lots of Irritating Sets of Parenthesis.

The multi-thread/multi-core "future" is here today and many have come to the
conclusion that functional programming seems to be the best approach we can
see today (there's been a _lot_ of research into this since the '80s or
earlier, nothing else has really stuck to the wall; note that Microsoft's F#
dialect of OCaml is perhaps the first "mainstream" functional language). Lisps
have always had a good story there as the first widely used functional
language (well, technically most of them are multiparadigm but strongly
functional), with a strong mathematical basis (the lambda calculus). Clojure
takes full advantage of this.

Apropos of the above, Haskell, the ML family and maybe Erlang were probably
the only more popular strongly functional languages prior to Clojure, but for
many they are harder to master; Lisps are more straightforward, they are
dynamically typed, etc.

Basing it on the JVM makes a _big_ difference: for some it provides a warm and
fuzzy since Java is so widely accepted and the Java/JVM ecosystem is so big
and healthy. For many this provides an easier path to getting started, and if
you want to get real world stuff done quickly, there's all those Java
libraries and packages that can easily be directly called from Clojure and
that can call Clojure.

(Actually, running on the JVM makes it easy for pretty much everyone to get
started on most any platform, just download the .jar file and run it in the
JVM that most likely is already installed on your system.)

Rich Hickey has made a _lot_ of good choices in designing the language and its
core libraries; it "feels" like a good fusion of Scheme and Common Lisp,
richer than the former and not at all crufty or impossibly massive like the
latter.

The community is _very_ functional, so to speak ^_^. There's one Google Group
where most of the action happens, it's very friendly and helpful and nasty
people are _not_ tolerated on it.

~~~
morphir
Many good points here.

 _Rich Hickey has made a lot of good choices in designing the language and its
core libraries; it "feels" like a good fusion of Scheme and Common Lisp,
richer than the former and not at all crufty or impossibly massive like the
latter._

Could you give some language design examples that differs clojure from other
lisps?

I heard someone speak about 'data' is separated from 'code' in clojure.. any
examples of this?

~~~
hga
(Note: I don't know much about EMACS Lisp, but obviously it's mostly for use
in EMACS and unlike all modern Lisps it's dynamically scoped, an early error
in the Lisp family that Scheme started to fix and that was the biggest change
in Common Lisp from its non-Scheme ancestors.)

The biggest is that Clojure is what I call "strongly functional": it's not a
pure functional language like Haskell (where you e.g. do IO in monads, which
call pure functional code) but e.g. its data structures are immutable. With
that foundation, made practical with its solution to the trivial update
problem, much can be done.

Hmmm, for that matter, the Scheme and Common Lisp standards don't address
concurrency _at all_ (Common Lisp is frozen in amber and Scheme hasn't gotten
to it yet). There are many implementations for this, of course, and maybe even
some de facto community standardization for Common Lisp (can't remember the
details, I moved fully to Scheme in 1984 and am in the process of moving to
Clojure now), but this is not the sort of thing you can address with a library
like networking (with the exception call/cc games with Scheme as I recall).

Scheme and Clojure are Lisp-1s, variables have one value, which might be a
function. For backwards compatibility Common Lisp is a Lisp-2, variables have
value values and function values, which gets used depends on the context.

At its base I'd say Clojure is higher level than Scheme (which pretty much
only has a base) and Common Lisp. E.g. in either you can easily do lazy
evaluation, in Clojure it's heavily used in the sequence library.

A very big thing is Clojure's collections. Common Lisp and Scheme are LISPs,
LISt Processing languages where the list is the alpha and omega and things
like vectors (one dimensional arrays) feel tacked on. Clojure provides a
unified collection abstraction with a variety of concrete realizations. The
most important ones are lists, vectors, maps (key value pairs) and sets
(collections of unique values), and the first three are first class citizens
in terms of syntax ( (), [], {} ).

The biggest thing that will hit a Lisp veteran is how collections other than
lists are used in the special forms (syntax). A bunch of them intelligently
substitute vectors where only lists were used in previous Lisps. E.g. fn is
the Scheme equivalent of lambda and the parameter list is a vector. E.g. the
following return a function that adds two numbers:

    
    
      (lambda (x y)
        (+ x y))
    
      (fn [x y]
        (+ x y))
    

There's a fair set of things that are fallout from it being built on top of
the JVM (note, it started out with JVM and CLR support, the latter was dropped
to speed development of the language per se and has been revived
independently). E.g. for security reasons the JVM doesn't offer native tail
call optimization (this will hopefully be fixed in the next version), so there
are a variety of hacks to achieve the same result, most notably the recur
special form.

Many people like this: if you accidentally put/move a recur to a non-tail call
position, you get a clear error instead of blowing your stack or running
slowly.

There are nil/null/true/false details that are partly driven by the JVM and
partly due to the emphasis on functional programming.

A concise overview can be found at <http://clojure.org/lisps>.

As for "'data' [being] separated from 'code'" ... I'm not sure what he meant.
Code is more than lists now, but it's still homoiconic
(<http://en.wikipedia.org/wiki/Homoiconicity>), it's all readable, the
function read groks vectors ( {} ) and maps ( {} ) just fine.

------
yummyfajitas
One of the big problems with lisp (and other such languages) is library
support. Being on the JVM and making java easy to access makes that a moot
point.

So yes, the JVM does make it cool.

------
gtani
Tim Bray, Ted Leung, Cliff Click asking hard questions bout STM/MVCC vs other
concurrency mechanisms;.

<http://www.tbray.org/ongoing/What/Technology/Concurrency/>

[http://www.sauria.com/blog/2009/10/05/the-cambrian-period-
of...](http://www.sauria.com/blog/2009/10/05/the-cambrian-period-of-
concurrency/)

[http://groups.google.com/group/clojure/browse_thread/thread/...](http://groups.google.com/group/clojure/browse_thread/thread/5c7a962cc72c1fe7?hl=en)

[http://blogs.azulsystems.com/cliff/2008/09/jvm-language-
su.h...](http://blogs.azulsystems.com/cliff/2008/09/jvm-language-su.html)

<http://wiki.jvmlangsummit.com/pdf/36_Click_fastbcs.pdf>

------
ThinkWriteMute
The JVM is actually what is keeping me from Clojure. A crazy reason, for sure,
but Java has pretty much burnt all my fingers.

~~~
jasoncwarner
That is a crazy statement! I can understand not liking Java (same boat here),
but the JVM and Java are two completely distinct things!

Languages like JRuby and Clojure, which are fantastic languages, have near
zero to do with Java. In fact, you can do most everything you want to do and
NEVER touch java code. You can, however, access the Java libraries if you so
choose (hence the power of working within the JVM).

Not liking Java should never be thought of as not liking the JVM.

~~~
Andys
What if the JVM was one of the reasons you didn't like Java?

~~~
hga
Wait a while; Rich has started thinking about the rewrite of the Clojure
compiler in Clojure and that will provide a great foundation for other back
ends (LLVM looks tasty).

