
What's Special About Lisp? - aerique
http://kresimirbojcic.com/2011/08/02/whats-so-special-about-lisp.html
======
Homunculiheaded
I do love ruby and feel that it's metaprogramming techniques to allow you to
easily emulated many features of Lisp's macros.

That said the author missing an obvious thing here. They key with macros is
that they allow you to alter syntax (not calculate values as many who try
initially misunderstand them), and s-exps are essential to being able to do
this (because they are effectively an abstract syntax tree).

I say this is obvious because the example itself demonstrates this. The lisp
code in the end looks very much like the ruby. Being able to extend syntax
means that if you like ruby you can make your lisp work more like it. Now try
to reverse this example, make a ruby library that emulates a lisp style, I
think you'd find it much more difficult, and expensive.

The other important thing to not forget is that this syntax transformation
happens at compile time. One of the reasons that Ruby has a reputation for
being slow is it has to keep track of a lot of metadata and all sorts of look-
ups to do a lot of the metaprogramming (which is why people should make better
use of it, you've already paid for it). In Common Lisp all this transformation
is free during runtime. Think of a common issue with JavaScript: no implicit
return. If Lisp did not have implicit return you could define a macro 'defr'
which allowed you to define functions like you normally do, but always know
they return a value. Instead you need to use CoffeeScript.

Finally people do still write plenty of Common Lisp, they're just a smaller
community. Not long ago I wrote myself a very practical tool to process a
specific file format, with it's own mini-dsl, an order of magnitude faster
than similar libraries (albeit with intentionally less functionality) and all
in 200 lines of Common Lisp.

~~~
cema
If you like Lisp, take a look at Clojure. I know it has been highly hyped
here, but seriously, a very interesting language, which combines the beauty of
lisp and practicality of java runtime.

(Edited: awkward English.)

------
invalidOrTaken
I feel for the author and have recently come to a similar (read: _not same_ )
conclusion: Lisp is pretty crappy for maybe 90% of the work being done out
there. The more easily-accessible and popular a domain is, the worse Lisp will
be for it. This isn't because Lisp magically gets worse; it's because other
languages get _better_ , through libraries. Even if nine of ten libraries are
crappy, there are enough people in the space (remember, it's a popular domain)
that _something_ good will come out of it, and eventually everyone will
basically settle on a few good choices.

Lisp programmers, when using Lisp for what it's best at, don't use libraries.
There _are_ no libraries for what they want to do, because what they're doing
is obscure and/or hard.

Lisp is best at doing new things that have never been done before, because
it's basically a language for writing libraries. As such, it prospers in
unpopular fields.*

This makes it hard for lisp evangelists to be taken seriously. If you're to
show someone a hard graphics problem written in lisp vs ruby, your reader has
to understand graphics programming first. But calculating primes? Anyone can
do that. Which example do you think will get more mindshare?

To summarize: Lisp is great at things you don't hear about.

* One reason Viaweb succeeded using Lisp for the web was because the web was still this exciting frontier and no one had really done anything with it yet. I'd go so far as to say that Viaweb wouldn't succeed today---they'd get trashed by the likes of Weebly, which is written in _php_ for crying out loud.

~~~
gaius
I think it's more subtle than that. An interesting program usually contains
parts that are "easy" (e.g. interfacing with a database) and parts that are
"hard" (e.g. complex algorithms). To be productive, you would want to get the
easy bits out of the way so you could concentrate on the hard bits.

Making Python or Scala talk to Oracle (for example) is so trivial you can
write that bit of your program in no time at all, then get onto the
interesting stuff. In Lisp, you have to spend significant time on this trivial
stuff. So if you are writing a program on your own PC for your own use, then
Lisp is fine. If you are programming anything that is going to run on existing
infrastructure or interoperate with other programs, it's very difficult to
justify the additional effort of using Lisp.

And I know a bit about this: I wrote Oracle bindings for OCaml! It was fun,
sure, but can I justify it when there are already Python bindings? Hmm.

~~~
bretthoerner
> In Lisp, you have to spend significant time on this trivial stuff. So if you
> are writing a program on your own PC for your own use, then Lisp is fine. If
> you are programming anything that is going to run on existing infrastructure
> or interoperate with other programs, it's very difficult to justify the
> additional effort of using Lisp.

Remember: Lisp is a family, not a language.

The best counterexample to your claim is: <http://clojure.org/>

I'd argue even CL covers a lot vs your claim (but please don't make it my
arguement, focus on Clojure) with QuickLisp: <http://www.quicklisp.org/beta/>

------
swannodette
Having spent 3 years with Clojure, I believe that Lisp macros are just as
powerful as they say. But no need to take my word for it ... checkout the
paper "Languages as Libraries" by the folks behind Racket.

I've created 3 libraries that I think would be exceedingly difficult,
excruciating, or impossible to write with the _performance_ and the _level of
control over syntax_ in anything but a very good Lisp:

<http://github.com/clojure/core.logic>, efficient embedded Prolog in 1K LOC

<http://github.com/swannodette/match>, in progress implementation of a state-
of-the-art OCaml pattern matching algorithm

<http://github.com/swannodette/delimc>, delimited continuations

------
saurik
A ton of responses and no one mentions the one-word answer?

"homoiconicity": the property of a language whereby code written in said
language is stored, in a natural and immediate fashion, as a data structure of
the same language

What this means for Lisp is that if you want to manipulate Lisp code, you
aren't dealing with some crazy complex AST: you can actually /see/ how the
code is parsed by looking at the code itself, as the code is actually typed
using the serialization format for the primary data structure of the language:
S-expressions.

So, you aren't just creating a little "DSL" by using some built-in syntax
tricks like "implicit last argument block", but instead are able to write code
that modifies code and generates code as easily as if you were writing the
original code in the first place: the comparison to Ruby is therefore
fundamentally flawed.

(Finally, as an unrelated bonus: the parser for Lisp is also written in Lisp
and available during the execution of Lisp, so you can have code that modifies
and extends the parser itself allowing you to fundamentally alter the syntax
to, for example, look like Ruby; this mechanism is called "reader macros", for
the record.)

~~~
probably
Please excuse my ignorance here --

> instead are able to write code that modifies code and generates code as
> easily as if you were writing the original code in the first place

Is this often done? I know it is conceptually possible with the advantage
being that the same functions used to manipulate lists and data are available
for this task, but I got the impression that not many people _actually_ do
this? For instance...

[http://stackoverflow.com/questions/6480053/modifying-
functio...](http://stackoverflow.com/questions/6480053/modifying-function-
saving-to-new-function-in-lisp)

~~~
saurik
AFAIK this is actually incredibly common. The example that springs to my mind
is people writing matrix libraries that manipulate the code to "compile" it to
use more efficient algorithms. People do this kind of thing in C++, such as in
Blitz++, but you end up having to pull heroics with the type system (and end
up with some pretty abused syntax at times) to accomplish what is much easier
in a homoiconic language like Lisp.

------
prospero
The macro example used is meant to be instructive, not a demonstration of how
powerful macros could be.

Consider <https://gist.github.com/1119534>, which demonstrates a pattern-
matching syntax that (at compile-time!) constructs a minimal traversal of the
data structure to find a match. The only way to do this in a language without
macros is to write your own compiler.

~~~
copper
Or Shriram Krishnamurthi's Automata via Macros - a beautiful little nontrivial
example of Scheme macros:

[http://www.cs.brown.edu/~sk/Publications/Papers/Published/sk...](http://www.cs.brown.edu/~sk/Publications/Papers/Published/sk-
automata-macros/)

------
sjs
> You can fake it anywhere else with more or less work

That doesn't make sense, because there's no way to twist it. It's more work
and duplication. I want macros all the time in JavaScript and that is a pretty
flexible and dynamic language.

Most of Lisp's other features are common now. Macros are still a big one but
you don't need them every day. Lisp has powerful exception handling but I'd
rather have Erlang style error handling and recovery.

Lisp's draw is waning but only because our languages are lispy in ways that
really matter. We have dynamic, garbage collection languages with REPLs and
built in high level data structures that are even better because we have
native syntax for them. I don't want to keep track of N different kinds of
assoc lists... and I really like Lisp.

~~~
vseloved
> Most of Lisp's other features are common now.

Special variables, restarts and flexible reader are some of the basic
features, that are not only uncommon, but, actually, unseen in any other
language. Just to name a few.

~~~
sjs
Thanks, I knew I'd miss some since I'm only an amateur Lisp hacker.

Factor has a cool and flexible reader too but it's pretty far from mainstream.

------
ihodes
I had similar thoughts when I was first learning a lisp. Unlike the author, I
was enamored with the lack of syntax and the expressive power that was there.
Sure, it's a Turing-complete language like any other, but for me it was a
pleasure to hack with. Not only that, but you can actually do things with it
(manipulate the language itself, from within the language itself…whoa) that I
would only later realize the power of. Turns out you rarely need to use that
power.

For instance, I'd do (untested):

    
    
        (defn prime? [x] (every? (fn [n] (not (zero? (mod x n))))                                                                                     
                                 (range 2 (Math/sqrt x))))                                                                                            
                                                                                                                                                      
        (doseq (map pr (filter prime? (range 0 20)))) 
    

for the same effect. And I really was happy to write that. It makes sense.

NB: I'd never put such code into production, and I think it should be a
warning sign that a purported problem in a language/dialect be based around
minimal experience regarding an example.

------
rpearl
I mean, yes, the biggest win of lisp over other languages is that the
metalanguage _is_ the language. That is what is special about lisp. That is,
when defining a macro, you are simply treating the program itself _as data_.
Since code and data take the same form, this is a really natural way to
metaprogram. In most other languages, it is... not.

Now, the featured article picks a... not very good example, for this feature
of the language. But that doesn't mean that metaprogramming is useless. Much
of a (big) lisp program is building up a domain specific language out of
macros, then solving the problem at hand with it. This is the biggest power of
lisp, and also the biggest weakness--every lisp program is written in a
different language.

In lisp you express your _problem_ in macros, and then express your _solution_
in the language you've built up.

------
cabalamat
Homoiconicity is part of the answer. The other part is that Lisp is built up
from a small number of axioms (probably the smallest such number) that are
Turing-complete and at the same time are a language that people would actually
want to use.

As pg says: "In 1960, John McCarthy published a remarkable paper in which he
did for programming something like what Euclid did for geometry. He showed
how, given a handful of simple operators and a notation for functions, you can
build a whole programming language. [...] It's worth understanding what
McCarthy _discovered_ [my emphasis], not just as a landmark in the history of
computers, but as a model for what programming is tending to become in our own
time. " <http://www.paulgraham.com/rootsoflisp.html>

Why does pg say McCarthy discovered Lisp, not invented it? I think because
it's something of such simplicity that one can imagine others inventing the
same thing. So if humans contacted intelligent aliens, it wouldn't surprise me
if they had independently invented Lisp, just as it wouldn't surprise me if
they'd invented prime numbers, or cartesian co-ordinates.

------
stephth
From one page the author linked to [1]:

 _"Because coders DO NOT LIKE LISP. Most programmers find Lisp unpleasant and
unnatural to use. They're not idiots, they're not ignorant, and they're not
willfully choosing a less-powerful or less-efficient tool, they're choosing
tools based on what makes them productive and happy."_

The _"profound enlightenment experience you will have when you finally get
[functional programming]"_ [2] is a mystery that I've been trying to figure
out, albeit slowly since the day only has 24h. I've gone through the Peepcode
video on Clojure and I couldn't find an answer, and I didn't even feel
attracted to the language, quite unlike my first Ruby experience.

Then the other day I watched Matz - creator of Ruby - talking about Ruby 2.0,
and he used the word "happy" multiple times to explain how he wants developers
to feel when using his language, and I thought of how brilliantly he's
succeeded. I have now spent more time coding in Objective-C than any other
language (iOS development), and every hour I code Objective-C I miss Ruby and
how happy it makes me feel.

I find that happiness is highly overlooked in discussions about programming.

[1]
[http://discuss.joelonsoftware.com/default.asp?joel.3.371875....](http://discuss.joelonsoftware.com/default.asp?joel.3.371875.57)

[2] <http://www.paulgraham.com/avg.html>

(edit: formatting)

~~~
anghyflawn
Have you looked at "The Joy of Clojure"? I thought the authors did a very good
job of showing why exactly they're so excited to be working with the language.

In any case, this is very much a question of discourse. For historical reasons
Lisp (at least Common Lisp) seems to have this reputation of being associated
with deadly serious people, or alternatively smug lisp weenies, while Ruby
people talk about how happy it makes them feel all the time, even though there
are plenty of people who clearly have fun with Lisp (even "crufty" "old" CL),
and I'm sure many people would regard working with Ruby a chore. I mean, to
each his own, I honestly can't imagine there's an objective scale on which CL
(much less exciting new languages like Clojure) is "less fun" than Ruby.
Things like homoiconicity, on the other, are objective criteria for comparing
languages. There are plenty of reasons to like (say) Python better than (say)
CL, but to say that homoiconicity or restarts or MOP are no big deal because
if you try hard enough you can replicate 95% of that functionality in (say)
Perl is a different question entirely.

~~~
stephth
_to each his own_

That was pretty much my point. That _maybe_ the solution to the mystery of the
_"profound enlightenment experience"_ around Lisp is that it makes some very
happy, but not me.

 _Have you looked at "The Joy of Clojure"?_

I haven't, I'll look into it, thanks. I haven't given up on solving that
mystery yet.

------
udzinari
I think whole point of comparing programming languages from this angle is
pointless. You should not go and judge a language by several phrases. Go
speak/write/read it for a while, learn some slang.

Like all other languages, programming languages are also just that, languages
- tools to express your thoughts. To me and many others Common Lisp reduces
the friction between those thoughts and written description of them. It is so
much more to this language than just its syntax and politics. It is joy to
develop in thanks to SLIME, it almost never gets in your way, it performs, it
has wisdom of half a century and people who possess it. Yes, it is far from
perfect, but then again - there is no perfect language! and even if there was
one it would sound like those studio processed pop-star voices rather than
perfection to me, because it would still superimpose its perfection over you
own views.

In other words, please don't judge the language by how you can pronounce "how
can I get to the city centre", it sounds similar in most.

Now all this spoken/written language comparison might sound weird to you, but
to me it makes perfect sense, because programming to me is nothing but a
dialogue between me, computer and the future version of me reading the source.
And I like the language which allows me to do this on my terms, rather than
that of Guido, Matz or whoever. And to _me_ Common Lisp is pretty close to
that.

P.S. Just as a side note, folks on #lisp and #sbcl are one of the most
pragmatic and intelligent people I have ever seen, I learned more from their
discussions than by reading a couple of books. To any of you reading, rock on
Lispers ;)

------
scottjad
> In Lisp I get a feeling that nothing was done since '58. <snip an ignorant
> rant about macros>

Well, macros for one didn't exist in Lisp in 1958.

------
_pius
I know and enjoy Lisp, but I don't use it anymore. I do, however, use Ruby,
which is an acceptable Lisp.
[http://www.randomhacks.net/articles/2005/12/03/why-ruby-
is-a...](http://www.randomhacks.net/articles/2005/12/03/why-ruby-is-an-
acceptable-lisp)

In general, Lisp doesn't seem special anymore because (1) language
implementers have taken Lisp's most important lessons and applied them to
their own languages and (2) said languages have become relatively popular.

A lot's happened since "Beating the Averages".
<http://www.paulgraham.com/avg.html>

------
eslaught
Evidence of people working in Common Lisp: <http://www.quicklisp.org/>

------
pnathan
Lisp works with me to get the job done. Other languages typically impose a Way
to get the job done.

I don't think like other language designers often. So I like a flexible
language.

------
agentultra
A Common Lisp variant of an excercise found in the Seasoned Schemer:

    
    
      (defun sum-of-prefixes (tup)
       (let ((sonssf 0))
         (loop for n in tup
               do (setf sonssf (+ sonssf n))
               collect sonssf)))
    

The variable 'sonssf' is an acronym for "sum of numbers seen so far;" this
function creates a list of sums of all numbers it visits as it traverses the
input list.

ie:

    
    
      (sum-of-prefixes '(1 1 1)) 
      => (1, 2, 3)
    
      (sum-of-prefixes '(1 2 3 4 5))
      => (1, 3, 6, 10, 15)
    

It's a simple bit of code that I go into in more detail with an example in
Python and Scheme: <http://agentultra.com/?p=670>

The reason why I think Lisp is a great language is that I haven't yet needed
to use any "patterns" in any of my (admittedly small) projects. Patterns, IMO,
are boilerplate code to work around the limitations of a language. I haven't
encountered a need for that in Lisp yet. It's a good sign to me.

I also have dynamically scoped variables, generic functions, parametric
dispatch (or multimethods or whatever you call it), macros, and a very
powerful OO system if I need it. Best of all is that all of it is unified by a
small amount of syntax, backed by a small set of axioms, and surrounded by a
wonderful (but small) community.

 _edit: Fixed the example output_

------
benwr
I hate to just insert a link into a comment, but this article is a much better
response than anything I could come up with:

[http://www.randomhacks.net/articles/2005/12/03/why-ruby-
is-a...](http://www.randomhacks.net/articles/2005/12/03/why-ruby-is-an-
acceptable-lisp)

~~~
nickik
That article is bullshit:

Ruby is a denser functional language than LISP. This is just not true! Sure
sometimes you have syntax suger in Ruby that makes something smaller but
othertimes you don't in lisp I can always make everything smaller with macros.
I would bet that Ruby is not shorter for most programmes.

His hole argument is based around that in lisp you have wo write (lambda ....)
and in Ruby you don't.

Ruby gives you about 80% of what you want from macros Ruby may give you some
of the power but there is a lot you cant do in ruby and its much, much harder
to do those things.

Ruby’s libraries, community, and momentum are good Thats nice but has nothing
to do with being lisp.

Not saying anthing against ruby but this article is just very strange.

------
demallien
I have a question for those that have done a lot of programming in Lisp: Is
macro programming a really big part of Lisp programming? I mean, what
percentage of a typical project would be macros?

I ask the question because you can achieve the same results in most dynamic
languages by grabbing the string representation of a function, run it through
a parser, modify the resulting AST and then regenerating the function string
before passing to an eval (CoffeeScript being a good example of this
approach). Sure, it's messier than in Lisp, but in return for the messiness of
macros, you get much easier to read syntax in most of your code. Is the use of
macros really such a big part of Lisp programs that it justifies the lack of
syntax everywhere else?

~~~
nickik
Macros are not something you need everyday (at least not your own macros) but
when you need them you really need them. CoffeScript is a good example, if
JavaScript would have been a real lisp there would be no need for CoffeeScript
at all because you could build it in JS.

Your example of meta programming is very very messy and putting eval
everywhere would also be a security nightmare and if you do it this way you
don't end up with nice syntax. <\-- People don't really use this because of
those reasons.

Macros are not messy to use they look like a normal function that meens often
you don't even know or care if something is implmented in a macro or a
function.

The other big part of the macros look like language build ins for example in a
REST-Framework you would have something like 'defresource'. The auther of the
framework can give you the best syntax to discribe what his library does.
(Look on Stackoverflow for DSLs in Clojure)

Writting good macros your self is a little harder and can look wired because
your just not used to code looking like this.

The USE of macros is a REALLY REALLY big part of every lisp programm because
the HOLE language is build on macros. Almost everything that is normally build
in the compiler is just a macro.

~~~
demallien
Firstly, CoffeeScript _is_ built in JavaScript. Does that make it a 'real'
Lisp?

Secondly, Lisp macros are every bit as big a security risk as using eval...
That is what the E in REPL stands for, after all. In both cases, if you are
taking input from source code, and not from outside sources, there is no
security risk.

Thirdly, yes, my example is messy. But it is still doable, and I just have a
hard time believing that this kind of programming is a major percentage of the
code of a Lisp program. To be clear on that comment, I can easily believe that
you end up invoking macros a lot, but I don't believe that a large percentage
of the code written for a project is actually macros. What percentage of code
in a typical project is macros? And how many of those macros can be easily
reproduced by using specialised syntax of a language such as ruby (optional
parantheses, blocks, re-opening classes, method_missing, etc)?

This is an important point, because if you only have a few hundred lines of
this stuff in a typical Lisp program, and it can be reproduced by using a
parser in another (dynamic) language, then the advantage just isn't that big.
For argument's sake, imagine having a module available in Javascript that
provides the Jison parser along with the Javascript grammar, which just re-
emits the original Javascript source. In addition, it has a nice API to allow
you to modify the grammar (adding / modifying rules). So far so easy, this
stuff already exists in CoffeeScript, go copy it from there. Now, having
loaded such a module, is Lisp really in a much better position than this
modified Javascript?

~~~
nickik
In any language you can build a interpreter/compiler for any other language
but thats not the point. The point is that you can do random AST
transformation at compiletime.

You think of macros as a kind of pay of for s-exp syntax. I have to say that
even without macros I would think s-exp syntax is nicer. Sure in Ruby you can
do alot when you play around with that suger stuff but this stuff often
doesn't come free. See this blogpost for an example of what I mean:
[http://briancarper.net/blog/579/keyword-arguments-ruby-
cloju...](http://briancarper.net/blog/579/keyword-arguments-ruby-clojure-
common-lisp)

Depending on what you do you are writting a lot of macros. In lisp the
interface to a library is almost always in a DSL style witch makes them easy
to use. See this list here: [http://stackoverflow.com/questions/3968055/are-
there-any-clo...](http://stackoverflow.com/questions/3968055/are-there-any-
clojure-dsls). In your own Application your maybe not going to need them that
often depending on what you do.

What you discribe is just a macrosystem. Having macros in a language with
syntax is duable (look at Dylan or Plot) but you will find that getting
everything nice and easy to use is much harder then you think. If CoffeeScript
has a macrosystem great. I don't really know CoffeeScript well enought. Could
you provide me with some nice examples of how people use this in CoffeeScript?

If I where you I would just learn enought lisp that you can trie it out
yourself.

------
lelele
What's special about Lisp? Simplicity. No syntax means you don't have to parse
code when reading it. Each construct's scope is clear. Whenever I code for a
while in Lisp and then have to go back to C or Java, I find myself
uncomfortable. Not so the other way around.

------
zitterbewegung
Look if you want a language thats actually new and people are doing stuff with
it go to clojure.

------
devth
Really like this counterpoint after all the LISP elitists so often snub other
langs. The Ruby version is much more elegant and readable, in this little
example. Would love to see more comparisons, specifically hacking around the
lack of macros in other langs.

~~~
aerique
Being a Lisp enthousiast myself I often find those LISP elitists are people
new to the language repeating the tired arguments we have heard so often
before.

~~~
devth
I'm learning clojure, and find it has a certain elegance, but I don't fully
"get it" yet.

~~~
spooneybarger
Both lisp(s) and smalltalk took me about 18 months of decently serious use
before I had a 'I get it moment'. Stick with it and it will come.

I'm hoping that if I keep at it with Haskell, that eventually I'll have my 'I
get it' moment with it as I think I can learn a ton from when I get it, much
like I did with Lisp and Smalltalk.

I've learned things from many different languages but the two I've learned the
most from where Lisp and Smalltalk.

~~~
tensor
It took me about a year to have a "I really get it" moment in Clojure.

