Programming Languages (CS302 2007S)

Paul Graham - What Made Lisp Different

Comments on:

Graham, Paul (2002). What Made Lisp Different. Web essay at http://www.paulgraham.com/diff.html (revised May 2002; visited 16 January 2007).


I could not think of an advantage of having a symbol type. Why does the author compare it with string type? Consequently I did not understand the importance points 7 and 8 of the article. Could you explain ?

We talked about this a bit in class. When you want values that aren't numbers, symbols are nice because you can choose the values and have values that are human readable (as is the case with strings), but comparison is efficient. You are right that this also contributes to point 8 (well, more to point 9).

Point 4, the concept that variables are pointers and values have types seems to go against strong typing. Isn't strong typing considered a good thing for a language to have? It provides a mechanism to catch programmer mistakes and ensures that the values stored in the variables are consistent. While Lisp's style of typing gives the programmer more options, it seems akin to how GOTO statements give the programmer more options.

Welcome to my favorite language design war. Graham and company would argue that good programmers don't need the restrictions that a strong type checker enforces. There are times to make your code adapt nicely, too. A famous case is in the mid-80's stock market crash, in which most market analysis programs crashed because the change in values was greater than could be stored in an int (or some such), but a company that used a Lisp-based system actually made a profit.

The fourth difference suggests that LISP is pass-by-reference. Wikipedia says that Scheme is pass-by-value (http://en.wikipedia.org/wiki/Pass_by_reference), was this a change that was made in the design of scheme? Why does Graham regard this as an advantage?

Yeah, it's one of those confusing things. Like Java, Scheme is pass-by-value, but the values you pass are references. So, if a parameter refers to one memory location, and you set! it, it now refers to another location. However, if you modify the thing it points to (typically, with set-car!, set-cdr!, or vector-set!), then you can see the effect.

Graham likes it because it's relatively efficient and because it's sufficiently limited that you are unlikely to have many aliasing problems, the typical problem with pass-by-reference.

The programs being composed of expressions feature of Lisp: wouldn't that make readbility very difficult In the case of the example given in the reading, where

(if foo (= x 1) (= x 2)) 

or

(= x (if foo 1 2)) 

So if you have the feedom to compose expressions however one wants wont that make reading programs difficult for a third party who might have an entirely different style?

Yes, that's a potential problem.

What exactly are s-expressions? Can you give an example? Also, Graham says s-expressions are an idea "recently reinvented as XML". What did he mean by that?

S-expressions are the basic building blocks of Lisp (and Scheme) programs. In the simplest form, a symbol is an s-expression, a number is an s-expression, and a list of lists is an s-expression.

XML, when done correctly, has a similar basic idea - A simple, recursive definition with not too many building blocks.

I don't really understand the use of running code at compile time. How does that benefit anything?

Think about C macros - Often, you can do some powerful code modifications (that is, change the form of the code) at compile time. You don't want a separate source file that someone might modify - you want to automatically rearrange the code while you're compiling.

I think the thing that most surprised me on reading this article was that lisp has been around for almost 50 years, but it seems like it just hasn't been used until more recently. I honestly, on hearing about LISP had the impression that it was a new development as far as programming goes, but as it turns out it's actually one of the two main theories about how to program, (prior to the invention of object oriented programming) and appears to have established a lot of the standards for what we now expect in any good programming language.

Well, it was actually used a lot in the 1970's and early 1980's (as I think Gabriel suggested in a prior reading), but it fell into a bit of disfavor. And it's still not used very much.

Why can functions in modern languages only return one value?

Um, Scheme, at least, can return multiple values. I'm pretty sure that Python or Ruby also supports that facility. I'm also not sure what this has to do with the reading.

More generally, it's a bit of a pain to work out a syntax for which it makes sense to deal with a function that returns multiple values. For example, in a C-like language, I suppose you might write something like the following.

a,b = foo(...);

However, it's not clear that's a great gain. In addition, if you want to nest functions (that is, apply one function to the result of another) it becomes exceedingly difficult to develop a syntax and semantics that will be clear to most programmers.

I don't understand the 9th difference

What don't you understand about it? In most languages, you read code, then you translate it to an executable, then you execute the executable. In Lisp, the steps happen together. For reading, that means that what you read earlier can then affect what happens later. For executing, that means that you can send the text of an expression to a program, and have the program evaluate the expression and use the result (making it possible to send some fairly complex requests between communicating programs). And, as Graham suggests, there are many other benefits, too.

In History of LISP, John Mccarthy writes that one of the features that have kept LISP a favorite over time is that it a list-based language. I was wondering why LISP's list-based property did not make it to Graham's list. Or is that what number 8 represents? I dont fully understand what No. 8 means.

No, I'd have to agree with you, Graham doesn't really seem to mention lists directly (and his use of lists is almost exclusively in terms of s-expressions).

Number 8 says that the notation describes trees, which it does. That is, a lists of lists is a tree. What is the notation? It's the idea that an expression is either a basic value or an open paren, a sequence of expressions, and a close paren.

Before LISP, did programmers use resursion in their programs that were written in assembly, or did they just do without?

There are no function calls in assembly, so there can be no recursion.

Disclaimer: I usually create these pages on the fly, which means that I rarely proofread them and they may contain bad grammar and incorrect details. It also means that I tend to update them regularly (see the history for more details). Feel free to contact me with any suggestions for changes.

This document was generated by Siteweaver on Sun Apr 29 11:27:20 2007.
The source to the document was last modified on Sun Feb 11 23:24:34 2007.
This document may be found at http://www.cs.grinnell.edu/~rebelsky/Courses/CS302/2007S/Readings/graham-different.html.

You may wish to validate this document's HTML ; Valid CSS! ; Check with Bobby

Samuel A. Rebelsky, rebelsky@grinnell.edu