
Why I love Common Lisp and hate Java - swannodette
http://kuomarc.wordpress.com/2012/01/27/why-i-love-common-lisp-and-hate-java/
======
Stormbringer
ITWARM (if this was a reddit meme)

Scumbag blogger:

Takes Tai-Chi for a couple of months, thinks he is qualified to talk about
'qi'.

Takes university course that touches on Java, dabbles in Lisp, thinks he is
qualified to discuss 'failings' of Java

Begs the question: if Lisp is so amazing and Java is so bad, why is Lisp a
failure in the marketplace?

\----

Remember that even Lisp's biggest recent (as in, in the ~17 years since Java
was released) success (Paul Graham selling his store-thing to Yahoo) was
quietly re-written in Java a couple of years later.

If your answer to the success/failure question is that people who use Java are
stupid-heads and people who use Lisp are wonderful geniuses, then may I
suggest that you haven't solved the dilemma, you've just multiplied the
entities by pushing it back a layer.

In any case, nobody cares about Java vs Lisp anyway. All the 'cool kids' in
that space (e.g. functional programming on the JVM) are into stuff like Scala
and Clojure. To ignore those makes the argument kind of pointless... it is
like having an argument between a Dodgers fan and a Patriots fan. The Dodgers
fan says the Dodgers are better because they hit more home runs than the
Patriots, and the Patriots fan says the Patriots are better because they score
more touchdowns.

It's just fundamentally stupid. Whereas if you compared Lisp and Scala, then
at least you'd be talking about teams playing the same sport. Yes, it's still
going to be as useful as watching a Patriots fan and a Dallas Cowboys fan
argue about which is better, but at least the argument isn't based on
fundamentallty stupid premises in that case.

~~~
nessus42
As someone who has programmed professionally in Java, Scala, and Lisp
(including Clojure), I might be qualified to assert that your sports analogy
is off the mark. All of these programming languages can be effectively used to
solve many of the same problems, though each language may excel at addressing
certain kinds of problems better.

For me, programming in a dialect of Lisp is just more fun than programming in
the other languages. Java is not fun at all, in comparison. And that's largely
due to the fact that it can be difficult in Java to write reusable code.
Consequently, you either have to repeat yourself a lot or tie yourself up in
knots to figure out a way to not repeat yourself. Repeating oneself is tedious
and boring.

On the other hand, static type checking can save you a lot of time debugging.
But it can also slow you down. It's probably a net win overall for most
problems, but for some problems, it is too restrictive. I find Scala to be a
happy medium for most problems, but I often switch to Python for small
programs, where the freedom from static typing can make development much
easier and faster.

I think the problem with Lisp is that most people just don't "get it". I'm not
sure why they don't, but perhaps it's a fact that I just have to accept. On
the other hand, I firmly believe that the state of software engineering would
be greatly improved if most programmers _did_ get Lisp. I can't say the same
thing about Java, however. In Java there isn't really much to get that you
wouldn't get by learning any other OO programming language.

~~~
6ren
Came across this while researching Turing's proof that a turing machine can
compute anything that is computable†. It's Church, comparing his and Turing's
approaches:

> computability by a Turing machine ... has the advantage of making the
> identification with effectiveness in the ordinary (not explicitly defined)
> sense evident immediately. (1937a: 43.)
> <http://plato.stanford.edu/entries/church-turing/>

If we see imperative languages (e.g. Java) as descending from Turing machines,
and functional languages (e.g. Lisp) as descending from Church's lambda-
definability, the same observation seems to apply. It's not that Turing's
approach is better, just easier to "get".

† _"computable" meaning "can be computed" (not "computable with a turing
machine"). Turing doesn't prove this formally - it's an intuitive appeal, and
no exceptions have been found. See section 9, page 249 (page 20 of the
pdf)[https://docs.google.com/viewer?url=http://www.cs.virginia.ed...](https://docs.google.com/viewer?url=http://www.cs.virginia.edu/~robins/Turing_Paper_1936.pdf)
_

------
gatlin
This feels like a lot of blog posts I write: the main content is probably
there, in the author's head, but not enough of it was put on the paper. What
we read instead is a slice of what I have no doubt in my mind to be a
fantastic essay.

I have recently begun a love affair with Racket and for a reason I think that
the author was ultimately trying to get at: the core syntax of any Lisp is a
minimalist tree and the semantics are lambda calculus (and abstract algebra to
help motivate types).

An REPL for Java could conceivably be written; AI is language agnostic; and
plenty of languages let you eval generated code; but Lisps are a window into
computation itself and it's very addicting.

~~~
hendzen
BeanShell is basically a Java REPL.

------
Deinumite
Any time I see someone complaining about how much effort it is to "just print
a string to std out in java" it boggles my mind.

Java was not really designed for ease of use in that way, clearly, and the
syntax and vm itself heavily lends it to networked programming.

This post would be better if it was "Why I love Common Lisp" with the half
hearted stabs at Java taken out of it.

~~~
koko775
Seriously. I've been doing Java for _years_ and it had been so long since I
wrote public static void main etc. that _I_ had to look it up. If you're
writing mostly classes to be run straight-up from the command line, you're
doing it wrong.

~~~
nessus42
I write Java programs that are designed to be run on the command line all the
time. Just what is it that I am supposedly doing wrong?

(That's not to say that most of the classes are to be run from the command
line, but each CLI program has to have a class with such a method.)

~~~
6ren
Speaking for CLI utilities (not apps in general), startup time is a killer.
Python, Ruby, Perl etc are so much faster (despite Java improvements) since
they began as "scripting" languages. One solution is to reuse a warmed-up JVM
(even faster if also reusing already-loaded classes):

    
    
      1. use a Java REPL, like BeanShell or Groovy (or write one).
      2. call a Java server from the CLI
    

I did (2) for a while, but not worth the saving of a second or so.

BTW: I find "you're doing it wrong" is so unreasoned that best ignored

~~~
nessus42
And if you use Spring, then the start up time is even worse! I do wish the JVM
had an option that would make it start up instantly, even if it meant that the
program would run slower. I wonder if the slow startup time has to do with the
JVM having to dig through .jar files to find stuff. I'm also surprised that
there isn't a way to cache the machine code generated by the jit so that the
machine code doesn't have to regenerated on every run. It seems very strange
to me that Java was invented by a Unix company, and yet it seems rather Unix-
hostile.

For the stuff that I'm working on, the 1 second startup time is no biggie
though. One CLI thing I wrote, for instance, crunched on genomics data for 3
minutes before finishing. By tuning tight loops and the like, I was able to
get that down to 15 seconds, but even so, the extra second there is no biggie.
Except for when the user uses the "--help" option. That extra second is
tedious.

~~~
6ren
Yeah, I'm puzzled by them not caching, e.g. they could copy an image of the
JVM in its starting state.

Maybe the "unix hostility" is due to platform agnosticism ("run everywhere"),
servant of two (or three) masters. e.g. issues in file libraries and AWT. But
py/rb/perl manage this OK... so idk.

BTW: bad practice to split up functionality (and loses many benefits of Java),
but a performance solution would be a script that handles the "--help", and
for anything else starts the JVM.

~~~
nessus42
I've actually used that hack for "--help", but I mostly use command line
parsing libraries (e.g., JCommander) that generate the usage message for you.
The users will just have to put up with the slight delay....

~~~
6ren
Yeah, it's a pain to setup and maintain. Bizarre idea: a source transformer
that knows about a CLI parsing library, to detect your usage of it and create
the help option in a scripting language - and also provide the packaging (for
the scripting language to start the JVM). Like Google's GWT for compiing a
Java subset to JavaScript.

Seems a bit of overkill, but I like the idea of a transformation operating
above the level of one language...

I suppose the logical conclusion is compilation of arbitrary Java source to a
scripting language, according to the performance characteristics required.
It's nice that it would retain semantics and be transparent to the user, while
rebalancing performance trade-offs.

~~~
nessus42
Nooooooooooooo! We've switched largely to Scala! (But we're sill stuck with
Java for GWT. :( )

~~~
6ren
Sorry, I don't follow. Doesn't Scala have the same JVM startup delay as Java?
Can do the same thing for Scala.

~~~
nessus42
Yes, Scala is a JVM language, and all JVM languages that I am aware of have
this start-up delay. One of the advantages of the JVM is that many different
languages can interoperate easily, but if you do source-to-source translation
to a non-JVM language, then the origin languages (e.g., Java) that have this
extra support become preferred, and thus discourage the adoption of the better
languages. E.g., GWT prevents us from completely migrating to Scala.

It seems as if it would be better to have have a JVM byte code to Python byte
code translator, or something like that, if such a thing is possible. But I
should think that it would be even better and easier to just have a version of
the JVM (or an option on the JVM) that starts up much faster.

If you're happy with just Java, doesn't BeanShell start up more quickly? (I
don't know, because I've never used it.)

~~~
6ren
> JVM byte code to Python byte code translator

Yes; or a JVM that starts up faster, and split the code between them in the
same way.

I'm assuming there's a fundamental trade-off between startup delay and average
speed, or we'd have had an instant option long ago. Um, if the problem is
loading etc jars, this mightn't work.

But one could still detect byte-code calls with hard-coded string arguments
(for "--help" and text) and compile that to python.

------
rbanffy
"A year and a half ago, a dear friend of mine send me this link."

pg's "Beating the Averages" is not known widely enough. We must promote it
more. We owe it to our friends who toil under inhumane conditions and work
with sadistic technologies.

BTW, pg, I'm taking my "Hackers and Painters" to PyCon 2012. Will you have
time to write a dedication? That is, if I get the book back from the colleague
I lent it to. ;-)

------
freshhawk
Well if the author took the same care in determining that Lisp is better than
Java that he did in "confirming the existence" of real life magical powers
through Tai-Chi then why wouldn't I listen?

------
rluhar
I understand that Java is verbose and does not have the same "instant"
feedback loop that a language with a fully supported REPL has. But I do not
agree with the assertion that Lisp would be a good substitute for Java as the
core instruction language in a University course. If people are having trouble
getting their head around Java, I think they would struggle with Lisp. Java,
in it's simplest form can be written in a very imperative manner. Most people
think sequentially, and if you are getting started with programming, writing a
simple little program in Java, IMO, is easier than something like Lisp.

I am not saying Java is better, just that it has less cognitive overhead than
Lisp.

I studied both Java and Haskell at University and found it much easier to get
going with Java than with Haskell (I hacked lots of QBasic - I am getting on a
bit - when I was a kid). Actually, I think a language like Ruby or Python
would be much better suited for an undergraduate / dual major than Lisp or
Java!

~~~
spacemanaki
The authors of How to Design Programs use Lisp (well, Racket/Scheme) and they
are some of the most careful and thoughtful CS educators, who are appear to be
thinking deeply about CS pedagogy (at least, this is the impression I get from
reading some of their papers and some of HtDP). So I wouldn't be so quick to
write off Lisp as an intro language over Java.

"I studied both Java and Haskell at University and found it much easier to get
going with Java than with Haskell (I hacked lots of QBasic - I am getting on a
bit - when I was a kid)."

I think Java is arguably closer to Basic than it is to Haskell, so this isn't
really a very fair or representative data point. (I don't claim that non-
programming undergrads taking CS 101 would be more successful if started with
Haskell instead of Java, although I believe that's not unheard of).

~~~
rluhar
Thanks for your comment. I will take a look at the book you recommend.

To be honest, it has been a while since I was an undergraduate!

On a related note - how easy is it to transition from having first learnt how
to program in Lisp (or a functional language) to programming in Java or C++? I
have seen lots of blog posts about doing it the other way around (Java to
Lisp). I would imagine that also requires a cognitive leap ..

------
arturnt
The first thing that anyone who doesn't know Java complains about is running a
main method, which no one in the Java world does 99% of the time. This is
probably the first thing you have to do in a Hello World Java tutorial, but
has nothing to do with Java.

There are some poor design choices in Java like no method overriding, mix of
primitives and their boxed equivalents, lack of closures, or first class
functions, confusing equals semantics, generics verbosity, etc. But main
method is just moot.

Also it has nothing to do with superiority of Lisp over Java. Lisp has a
different philosophy it's a functional language, while languages like Java, C,
Ruby, Python etc are all imperative (see
[http://en.wikipedia.org/wiki/Functional_programming#Comparis...](http://en.wikipedia.org/wiki/Functional_programming#Comparison_to_imperative_programming)).
I think a better article would be about the virtues of each style and when to
use which.

~~~
nessus42
One can program in Lisp in an imperative manner very easily and likewise one
can program in Python in a functional manner very easily. The big difference
between Lisp and Python (or Ruby) is not the functional nature of Lisp, but
rather it's homoiconicity.

Re Java, I write CLI programs in Java all the time. It's fine for that, other
than the annoying 1 second startup time.

------
wcdolphin
It is too bad your example does not really convey anything interesting about
the differences between clisp and Java.

The only thing I get from your essay is that Common Lisp has a REPL, which is
sad because clisp is actually fun and interesting, and has a lot of VERY
DIFFERENT things going for it.

Size of source code has never been a measure of the power of the language.

~~~
tsotha
I agree a "hello world" program is a good place to start learning but a
terrible place to start comparing. To be fair, though, to really show the
benefits of Lisp style programming you'd have to write something quite a bit
longer. Long enough, in fact, you'd have trouble enticing people to read it.

------
tsotha
>Lispers like to pick on Java. It makes sense, because Common Lisp has
everything that Java lacks.

But Java has a lot of things Common Lisp lacks, too. A GUI package. Network
programming. Cryptography. Yes, you get modules for all those things. But
having them in the core language means you know they're always available no
matter where your code is running.

I like Lisp, even with its painful syntax and poorly named internals
(Seriously. "cdr"? "endp"? Was there a Great Keystroke Shortage in the '60s?).
But it doesn't have the ecosystem for actually producing a product to anywhere
near the extent Java does. There's a _reason_ Java is used so much more widely
than Lisp.

In terms of syntax, I like what Rich Hickey did with Clojure. You still have
all the Lisp functionality but it's a lot easier to read.

~~~
hythloday
> Seriously. "cdr"? "endp"? Was there a Great Keystroke Shortage in the '60s?

Well...yes? When jaw-dropping storage is a 1 MB hard disk, things like
function names really do make a difference, especially when they're called so
frequently. For the same reason, C89 identifiers are only 6 characters long
(and hence the C naming convention of things like "strdup" rather than
"duplicateString").

~~~
tsotha
Sure, because you can fit six characters in 32 bits. But still... those
constraints are no longer with us, and there's a limited amount of historical
cruft people learning a language today should have to deal with.

~~~
codehalo
How do you fit 6 characters in 32 bits? What encoding / context? BTW, there
was a Great Memory Shortage.

~~~
tsotha
Something like this:

<http://en.wikipedia.org/wiki/DEC_Radix-50>

