To Lisp or not to Lisp, that is the question.

Musings on Lisp by a routinely Pythonic programmer

Last week I did some maintenance on various Python projects I haven't touched in years (literally), and I was surprised by how easy, almost trivial it was to reorient myself and make the necessary changes.

That observation came at the right time because I've been reading up on Lisp dialects for a while now and questioning whether or not I should be programming in Lisp instead. Lisp enthusiasts (converts?) certainly make persuasive arguments, typically advocating Lisp as the one-true-language with near religious zeal.

As programming languages go, I'm not very loyal. Over the years I've programmed in the usual assortment of languages (e.g., C, C++, Java). Then I discovered how much more productive I could be using a high-level interpreted language and I fell in love. With Perl. The affair lasted a few years until I realized she was a capricious, evil mistress and I left her in disgust for a younger, more elegant programming language: Python. With which I've been living happily ever after. No complaints. I have a happy text life. But sometimes, lying in bed late at night, my mind wanders and I wonder, if there isn't something even better out there for me. Just waiting to be discovered...

Could Lisp be that temptress?

Here's the thing: I've done my homework and it seems to be true that the various Lisp dialects are inherently more powerful programming languages than Python.

The reason for this is that Lisp isn't really a language at all. It's more of a mathematical entity. You might say it wasn't invented but discovered. In fact if there is intelligent life in the universe and they have computers I'll bet they have something equivalent to Lisp too.

You see, other "languages" are compiled/interpreted into a tree of instructions. With Lisp, you write programs directly in a lightweight text representation of the instruction tree. The learning curve is substantial. If you've programmed in other languages many things need to be unlearned. And the result, with all of those parentheses can look intimidating to someone who's mind isn't used to Lisp.

What makes Lisp so powerful is that there is no distinction between data and code. Code is data. Data is code. Lisp macros take advantage of this by allowing you to execute code at compile time that generates your runtime program. Features that need to be built into other languages (e.g., support for object-oriented programming) can be added to Lisp as a standard library of sorts. At its core you can think of Lisp as a sort of meta-programming language.

All of this makes Lisp extremely powerful, but... wait for it... this power comes with a price.

Compared with Python, Lisp is much harder to read and much more verbose than Python. Lisp makes it easier for a programmer to create mind-numbingly complex code. If you think a big ball of mud is bad, imagine a program implemented in a programming language that is itself a big ball of mud. Of course, you can write good and bad programs in any language but Lisp gives you more rope to hang yourself since you can redefine anything and reprogram the language itself.

Since Lisp is so flexible when you try to understand a Lisp program there is a decent chance you are looking at a program written in a domain-specific programming language invented by the programmer that you need to learn and understand first before you can understand the program. It won't necessarily help much that this language superficially shares the parse-tree syntax of Lisp. Two functionally equivalent Lisp programs may be as different under the hood as two programs implemented in Haskell vs Erlang.

Whether it makes sense to pay the price for all this power ultimately depends on the type of programs you are writing and the type of programmers you have in your team.

In my mind just because you can implement your own programming language doesn't mean you should. I think it's only rarely a good idea. Programming languages are hard to design well. Usually, I'd rather let Guido and the other language design experts in the Python community carefully work out what features a language should have rather then hack out my own.

Unless the inherent complexity of a program is very deep (e.g., AI like tasks) and to dig in you actually do need the power to extend your programming language. In that case, Lisp might be a good choice if you have programmers you can trust not to abuse it.

Note that many famous programmers who know both still prefer Python for most programming tasks. Where Lisp is optimized for power, Python is optimized for simplicity and ease of use.


Clint Laskowski's picture

1. I wouldn't agree that Lisp programs are always more verbose than Lisp programs. For more complex programs, I'd argue Lisp can often be more terse and usually more elegant.

2. Isn't there a good arguement that Python is actually a member of the Lisp family? I thought I read that somewhere.

Great post on a dilema many of us are trying to resolve.

Liraz Siri's picture

1) I don't doubt that Lisp can be more terse than Python and perhaps even more elegant to a trained eye, but show a typical Python implementation to a typical non-Python programmer and a typical Lisp implementation to a typical non-Lisp programmer and I'd argue the Python version will be much more readable. Python reads like pseudo-code.

2) You might be interested in this article: on the relationship between Python and Lisp.

K''s picture

I would argue that python is more "readable" to nowaday programmers just because python is more close to other "Von Neumann programming languages" like java or c++. They are more familiar with the concepts inside python than Lisp. 99% programers seldom do functional style programming so that they feel it is hard to read.

Darth Darth Binks's picture

Python is a highly dynamic programming language, but it is not in any way a Lisp. It doesn't even have a quote operator. Python's parse tree is incredibly complex, consisting of many specialized types which aren't even documented.

In contrast, Lisp's AST is made out of the same data types that you use to represent all other data in Lisp. That's literally the defining characteristic of Lisp, and the reason for all those parentheses. If you don't implement S-expressions, then your language doesn't belong in the Lisp family. And before you mention Dylan, it still has S-expressions internally.

Adam's picture

So what does that make Reobl? A forth?

What's the defining characteristic here, homoiconicity? That includes Rebol and Factor(to an extent), where you can manipulate code as data (more so in the case of rebol)

Julia syntax implemented internally using lisp; so can we categorise it as such?

Following my intepretation of your intentions, I think the answer is yes.

The key concept here is getting rid of the complexity of the AST and making syntax as easily manipulatable as possible

David A. Wheeler's picture

Lisp-based languages have a lot of power, but they also tend to be hard to read.

So I started the readable Lisp s-expression project.  We've created new abbreviations that people can add to their Lisp readers, making it possible to create much more readable programs.

Please check us out at: - I think you might find what you're looking for.


trongable's picture

@David A Wheeler. -- I doubt your going to improve lisp by trying to make it like any other programming language. All your efforts are going to do is at best dumb down lisp and make it harder to do what it was designed to do. Lisp in effect is a programmable programming language, which inherintly cannot be make readable by the general population of programmers. Its a personal programming language for power not for easy coding styles or reading. Its a swiss army knife with atomic power. If you feel you need to ruin someone elses pet project, then do it yourself in python cause thats the end result of your stupid mentally challenging interfering junk ideas. Please do the world a favor and either stop using lisp style languages or stop programming all together. I sincerely hope you are not in charge of any thing at all at any teaching college or large enginerring company because your ideas are the opposite of professional and also opposite of academic. Please just go away.



An actual professional programmer.

David A. Wheeler's picture

"I doubt your (sic) going to improve lisp by trying to make it like any other programming language."

I'm not trying to make Lisp like any other programming language.  There are many other perfectly good programming languages; if you want them, you know where to find them.  Instead, I'm trying to devise a better, more readable notation for Lisp programs and data structures, without changing Lisp semantics.


"All your efforts are going to do is at best dumb down lisp and make it harder to do what it was designed to do. Lisp in effect is a programmable programming language..."

Of course Lisp is a "programmable programming language".  Indeed, there are many strengths in Lisp-based languages.  But Lisp syntax doesn't support many modern - or even 1960's - capabilities of programming languages, which makes it less suitable than it should be as a "programmable programming language".  Thankfully, this is fixable, and then we can take advantage of Lisp's strengths where they make sense without the baggage Lisp has grown up with.


"which inherintly (sic0 cannot be make readable by the general population of programmers."

Well then, why are you worried?  Yes, many people have said making Lisp more readable is impossible.  But I *like* solving impossible problems, and I think I have a solution.  As the proverb says, "The person who says it cannot be done, should not interrupt the person who is doing it".

There have been many failures in the past, but after reviewing past efforts, I realized that those notations tended to be non-general or non-homoiconic.  I'm devising a notation that is general and homoiconic, and thus, it should avoid past problems.  It's a harder problem than it appears at first, but it is not an impossible problem.

My approach is to add some new abbreviations to Lisp.  Lisp already has some abbreviations, for example, the expression (a b c) is really just an abbreviation for (a . (b . (c . '()))), and 'x is just an abbreviation for (quote x).  I'm just devising a few more.


"If you feel you need to ruin someone elses (sic) pet project..."

Lisp is not your pet project.  If my work means that those beyond an elite clique can take advantage of Lisp (where it makes sense), that is a good thing.


"An actual professional programmer."

Uh huh.  I've been writing Lisp code for about 30 years, and I've been programming for longer.  Some people have programmed in Lisp even longer, of course, but my point is that I've used Lisp long enough to understand how Lisp is used... and to understand the weaknesses of Lisp.   You may not like my solution, and that's fine, but I know exactly what problem I'm trying to solve.

I'm sorry for you that you can't see the problems of Lisp.  Most professionals, in any discipline, can see the strengths and weaknesses of the different tools available to them, and most professionals appreciate efforts to improve their tools.  But no one is making you change.  If you hate abbreviations, feel free to write (a . (b . (c . '()))) or whatever it is that you do.  The rest of us, who want better tools, will move on.

For those of you who are interested in readable Lisp notations, take a look at the Readable Lisp s-expressions project at We have developed 3 tiers of notation, and implementations.  We developed SRFI-105 (curly-infix) for Scheme; guile has already implemented it and included curly-infix in its latest release.

OnePressTech's picture obviously have some passion for the subject and some expertise. It would have been more helpful to the community if you had chosen a more positive approach than to just vent.

The world of computing is far more subjective than we would care to admit. Although there are some math-based elements to computing and some informational-theory based components, for the most part, computing is a subjective art...the opinion of a group of technologists as to how things should be organised.

Every element of the computing world is great for specific scenarios, average for most scenarios, and terrible for the residual scenarios.

It is always uesful for technologists to debate the strengths and weaknesses of an approach. It makes us ALL better computer scientists.

So you leave us wondering...what specifically is your perseived weakness in the proposed approach, all emotion aside!

Food for thought.


Tim (Managing Director - OnePressTech)

Samantha Atkins's picture

Wait.  Lisp is the "programmable programming language".  So if your Lisp programs end up longer and more complex than say your python programs then it is because you didn't bother to use the power of Lisp to create an elegant embedded language to express what you were doing.  Done well such a program is much easier to read than programs in other languages because it much more precisely matches the language and abstractions of the actual problem domain than any fixed syntax language possibly can.

Perhaps a large part of the problem is that the other languages are easier for a *programmer* to read as they are written in the normal non-Lisp style everyone has used many times.  But this is not the case when read by a non-programmer that has a more difficult time piecing together the normal imperative or even pure functional code and understanding how it applies to their actual problem space. 

I like Python quite a bit myself.  But it has plenty of asymmetric 'features' that I wish it was programmable enough to allow me to create and use something a bit cleaner on top of its basis.  I use Python more than Lisp because of the larger set of libraries and frameworks growing faster than what is available for Lisp.  But I know for certain that Lisp is superior as a language - just not currently superior for many types of projects.   

Timmy Jose's picture


Please don't generalize the readability of Lisp vis-a-vis other programming languages as something that needs to be considered along with the experience level of the person reading the code. Human minds naturally work infix, and that's what makes most Algol derived languages extremely readable, of which Python is arguably the most readable syntax. 

Lisp works alright for moderately complex code, but when complex mathematical expressions are involved, it becomes a veritable nightmare to figure out the actual mathematical formula. Consider, for instance, The simple solution to the quadratic equation,ax2+bx+c = 0. In prefix, the solutions might be written as:

(/ (+ (- 0 b) (sqrt (- (square b) (* 4 a c)))) (* 2 a)), and

(/ (- (- 0 b) (sqrt (- (square b) (* 4 a c)))) (* 2 a))

whereas in an infix language, the same might be written as:

(-b + sqrt(b*b- 4*a*c))/ (2 * a), and

(-b - sqrt(b*b - 4 *a*c))/(2*a)

Now to any normal human being, the latter would be infinitely more readable and natural to process. And this is for a simple mathematical equation. For something more complex, the readability would be even worse for prefix notation. Don't get me wrong, Lisp is a great language to write in, but readability is not its forte. Even amongst all the Lispo dialects, I find Clojure to be the most readable since Rich Hickey took the conscious decision to introduce [], {}, #{} and other symbols to the syntax. In terms of mathematical expressions though, Clojure suffers from the same deficiency.


Liraz Siri's picture

Hi Timmy,

Thanks for weighing in. The point regarding infix syntax being inherently easier to read and more in line with what we are used to in terms of natural notation is a good one, and one I hadn't really seriously considered before.

Cheers, Liraz

Mikhail's picture

But you may always define macro for infix notation in Lisp. See, for instance, Incanter:

You may define some reader macro and have the same notation. For instance:


Or even something closer to math:

$(-b+sqrt(b b - 4 a c)) / 2 a)

In Lisp it is up to you. You may use Readable Lisp macros. Anything...

But it is not always practical to have infix notation. Even in the examples you've mentioned. Because prefix notation makes you to abstract and to write something like that (Clojure syntax):

(let [sqrt-det (sqrt (- (* b b) (* 4 a c)))]

  [(/ (- sqrt-det b) (* 2 a))

   (/ (+ sqrt-det b) (* 2 a))])

And we instantly see the structure of equotions for roots. It is more verbose, but easier to read and reason about: i see that there are some invariants, and that the roots are fractions. And when i see that, i may instantly "optimize":

(let [sqrt-det (sqrt (- (* b b) (* 4 a c))) norm (/ 1 (* 2 a))] (map #(* % norm) [(- sqrt-det b) (+ sqrt-det b)])

So i cleanly see all invariants and differences. And it is because of S-expression notation, i just need to abstract to write things easier. And when i abstract them, i'll get more efficient code. And of course, i will abstract that too, and will write later only (roots a b c).

That's why readable is not so popular. We've already abstract a lot of things and don't need tools to write a lot of low level arithmetics.

John's picture

If by "normal human being" you mean someone who's been reading infix all their life, sure. But it's not something we are born with by any means. Try reading the equation from the middle outwards instead of left to right (again, don't be so narrow minded, there is no "natural" reading orientation).

foggy brain's picture

Hey man, 

Im only 17 so cut me some slack hey.  I know that the best part of my experience with lisp is generics. You can make generic code in some other languages but only lisp has truely generic functions. This has saved my home project from code base expansion several times. Also has given me one function to do many things that are related only slightly different. So consider the power of generics as well. 





Add new comment