Explaining Lisp to my Father
Posted Under: Computer Science, Misc, Programming, Programming Languages, Quote
Anyone who read my post last week knows that I’ve been trying to learn Lisp in my free time. My Dad has also noticed, and he occasionally checks on my progress.
A week or two ago, he threw me a curveball:
“How’s it going? Do you understand it all yet?”
“No. I’m making progress, though. I’m probably not going to have this down for a while. It’s a completely different way of thinking from the programming I normally do.”
“How is it different?”
I froze. He’s “Mr.-Fix-It,” and understands the rock quarry/asphault business inside and out. He’s very analytical, and it’s almost impossible to stump him with my favorite “Devil’s advocate” questions. However, aside from what I’ve told him, he just doesn’t know much about programming.
“Metaprogramming” and “first-class functions” wouldn’t have meant anything. “It lets you write programs faster” is a cop-out; he’s given me detailed explanations of his business. I wanted him to understand.
I was able to stammer out the fact that the language encourages breaking problems into smaller versions of the same problem (recursion), but that other programming languages also supported it.
I eventually told him that I hadn’t even thought about explaining the difference to a non-programmer.
“Well, if you’re ever able to come up with it, let me know.”
In college, I was a Computer Science tutor. I could explain most CS concepts that students saw in early C++ and Java courses to the layman on the street. However, I had nothing for explaining the difference between Lisp and C++ to him, which was a little scary. I spent some time dreaming up examples.
Functions
All models are wrong, but some are useful.
Abstract math notions are boring to most people, so I try to relate programming concepts to real-world items.
A fast-food restaurant is a great example of a function: An order and some money is input, and you get cheeseburgers, fries, a soda, and your change. Whether a person likes math or not, they know what a function is: you put something in, you get something out.
The idea is easily extensible to Object Oriented programming: all Burger Kings have orders, and you can place a specific order at an instance of a Burger King. A Burger King “is-a” fast food restaraunt.
I will use this metaphor to explain why Lisp is different from the programming I usually do (C++/Java/C#/Python).
Lambdas
Any restaraunt probably has a few different ways to order food: over the phone, at a drive-through window, at a counter, through a waiter, etc. However, there might be unofficial ways to order food: Bill Gates might write a letter requesting a buffet with a few hundreds slipped in as proof. Someone might tell the owner on his way to work that he’d like him to come back with a pizza.
The owner can easily define new ways to order food through a restaraunt.
Lisp, through “lambdas”, lets a programmer define new functions as easily as a restaraunt owner can devise new ways to order. The inputs and outputs are the same, but making new functions can have very low overhead compared to other programming languages.
Brevity
“Wiz Wit”.
This is my usual order at Pat’s in Philly. With just two words, I get a cheesesteak with Cheez-Wiz and fried onions in less than 5 seconds. The system is designed to maximize the number of cheesesteaks output per hour: orders are short, and you usually get your cheesesteak before you’re done paying [and sometimes, before you're done speaking!]
This lesson can be applied to writing: It’s easier to convey a short thought. Unless you are Charles Dickens or Neal Stephenson, economy of language should be a goal.
Lisp’s syntax is very simple and short, so you can usually convey a thought in Lisp much quicker than you can convey a thought in most other programming languages.
Macros
An order can come in several different forms: it can be written, it can be gestured, it can be be spoken, and it can be implicit.
A lot of programming languages let you generalize the details of what an order can receive. Most orders are the same, so you can handle the contents the same even though the orders are different. In C++, you could even use “templates” to write code that generates code that handles this idea.
Lisp takes this idea all the way to its logical conclusion through “macros.” You can easily write functions that define orders. The difference is that you can easily do this at any scope!
If you notice that all fast food restaraunts are the same except for color scheme, specials, and slogans, it is easy to write functions that define new fast food chains. If you notice that your functions for defining fast food chains are similar to your functions for defining hardware chains, you can write functions that generate these producers.
Lisp lets you easily do this manufacturing on a level that is unimaginable with any other language. It may be possible, but nothing beats Lisp’s ease-of-use.
Self-Modifying Code
The metaphor breaks down here, and I won’t force it. However, the idea is simple when it is explained.
Most programming languages are designed to modify memory. They all store their information in memory, retrieve it, modify it, and write it to memory again.
Some programming languages try to hide the fact that they’re based on a memory-modification model, but they are extremely similar to languages that don’t hide it.
Lisp, however, is written to modify lists. Lisp is also written using lists, so a Lisp program can be programmed to modify itself.
Conclusion
This is just the tip of the iceberg! There are a lot more ideas that lay beneath the surface here, and you can bet that I’ll think about how to explain them to an educated adult. However, this should get someone with passing familiarity to programming to understand what makes Lisp stand out: ease-of-use and brevity.
Popularity: 26% [?]

Reader Comments
All programming languages have what you’ve listed as being different about Lisp. If you’re trying to explain the difference, it would have been easier years ago before current programming languages borrowed most of the features.
Today, Lisp has only a couple of major differences. The first is the lack of syntax therefore it avoids emphasising any specific approach and therefore makes using any approach easier (and harder).
The second is the ability to quote code so it can be parsed and re-written. Any language with eval() has the same ability, but Lisp inherently formats all of its code to be easily parsed.
So Lisp really only differs from other languages in its ability to really gaze deeply into its own navel. If you do that for too many years, you become so brain damaged that you write a shopping cart and call yourself PG.
Nice read. I like the fast-food function example. Very good idea of explaining CS problems.
Thanks mate, and happy lisping.
My Father is a carpenter and a hobby mechanic. My best shot and explaining how Lisp is different would be something like:
Programming languages are collections of tools to make products. “Language A vs. Language B” is usually similar to “Saws and Hammers vs. Wrenches and Screwdrivers”. Lisp, however, is a collection of solid and useful tools that are amazingly made entirely out of Lego bricks. If you need a new tool, you can easily make one on the fly. You can even build configurable Lego machines that spit out custom Lego creations on demand. But, you have to be careful that you don’t end up with a shop full of oddities that even you don’t understand anymore.
Ok, how about for Self-Modifying Code:
Lots of fast food stores have a Comments and Feedback box, where someone can write their complaints about the order system, or their suggestions for changes. If these comments and complaints are sensible, they change the ordering system itself.
Lisp is a database of s-expressions which happens to have an interpreter for it.
Cory – fantastic analogy. It even explains why nobody uses Lisp:
“Unfortunately, although other languages can give you a beautiful, ergonomic wrench that’s well designed and pleasant to use, everything in Lisp has bobbles on top because it’s made out of lego bricks.”
Laurie,Cory: Thanks, great stuff.
Oh, and about other languages having these features too: Now, when you talk about dynamic languages, that’s true. But lambdas in Java or C++ haven’t yet materialized, and (in Java) perhaps never will. C# has these, but that’s only one out of 3. And macros: Never. No other language has such a meta-level of control with as little fuss as lisp.
I like the woodworking analogy, but I wouldn’t say Lego. I think one of the fundamental features of Lisp is that it’s written in itself.
So when you’re programming in Java, you’ve got metal tools (compiler, profiler, etc.) for shaping wood (your program). If you want a new tool, you have to find a guy with a metal shop — so nobody does. You have the tools you’re given, and that’s that.
But when you’re programming in Lisp, you’re writing in the same stuff the language uses. It’s more like metal working. If you need a new tool, machine yourself one. Now you’ve got new tools to bring to bear on the problem. You end up with your solution, and also a new set of tools specifically designed for it.
This is why Lisp makes you more productive: not because of any particular tool it gives you (like Perl’s regexps), but because you can build your own.
Asphalt?
Explaining spelling to my brother. Sorry, couldn’t resist.
Loved the post.
Well done Jake a solid explanation for a simpleton like me. Except I think that Charles Dickens could have benefited from some brevity in his writing. Sure his famous name tells us we should love, but waxing poetic for a page and a half about a piece of paper on the desk in the corner of the room makes me sick. It definitely was the worst of times.
Does it have to use metaphors? How about “We write programs to automate mundane tasks by making a machine do them for us, but when the problem get’s too complex, Lisp makes it possible to automate the programming operation itself, by writing a program to write the program for you”.
About closures: Most languages take a set of commands and executes them, but doesn’t do much besides the execution. I tell the language to do X and it’s done. With closures I can do stuff in the language with the commands themselves. I can tell the computer to take those commands and, say, execute them every 5 seconds or in reverse order or combine them with other commands to form a bigger program.
I don’t understand why the difficulty in explaining Lisp. The magic of this language, as you know, is all in the macros and the lambdas. These could be thought of as nothing more than a set of tools designed to make other specialized tools tailor-made to solve specific programming problems. While it is true that you can extend languages like C++/Python/Java with libraries, it is comparatively more difficult to do so. As a result, these languages tend to encourage the programming style where you contort your problem to fit the tools you have available on hand for solving problems rather than augmenting your tool set with the right tools for the job.
Maybe you could compare lambdas to the salad bar at pizza hut. You’re able to provide some money and you also specify how you want to assemble your plate from their stuff.
As soon as you provide the input, the restaurant lets you at the salad bar, in which case you generate your own output.
these are terrible analogies. what school did you get a CS degree at without having been exposed to LISP?
@Jayrell:
The school of hard knocks, my man!
What high school let you graduate with the double whammy of almost unreadable grammar and the inability to support your own arguments?
“Besides a mathematical inclination, an exceptionally good mastery of one’s native tongue is the most vital asset of a competent programmer.”