Question

I have seen many CS curriculums and learning suggestions for new programmers that call for the aspiring programmer to study a lisp interpreter that is specifically written in lisp. All these sites say things similar to, "its an intellectual revelation", "it is an enlightenment experience every serious programmer should have," or "it shows you hardware/software relationships," and other vague statements, particularly from this article taken from this reputable how-to.

The general sentiment of my question is, how does lisp achieve the above goals and why lisp? Why not some other language?

I am asking this because I just finished writing a scheme interpreter in scheme (taken from SICP http://mitpress.mit.edu/sicp/ ) and now I am writing a python interpreter in scheme and I am struggling to have this legendary epiphany that is supposed to come specifically from the former. I am looking for specific technical details between the two languages that I can exploit in their scheme interpreters to gain understanding about how programs work.

More specifically:

Why is the study of an interpreter that is written in the language it interprets so emphasized - is it merely a great mental exercise to keep the original language and built language straight or are there specific problems whose solutions can only be found in the nature of the original language?

How do lisp interpreters demonstrate good architecture concepts for one's future software design?

What would I miss if I did this exercise in a different language like C++ or Java?

What is the most used takeaway or "mental tool" from this exercise? **

** I selected the answer I did because I have noticed that I have gained from this exercise more skill in designing parsing tools in my head than any other single tool and I would like to find different methods of parsing that may work better for the scheme interpreter than the python interpreter.

Was it helpful?

Solution

At the risk of giving a "me too" answer, if you try it you'll see...

If you study computer languages, you're likely to get the impression that it's at least half about parsing. If you learn Lisp, you'll realize parsing the surface syntax is nothing more than a convenience for people (like most of us) who don't like Lots of Irritating Single Parentheses.

Then you could realize that a big price was paid for that convenience. In Lisp it is trivial for a program to build another program and execute it. In other languages it is an advanced technique, like doing multiplication in roman numerals.

Of course, nearly everybody would ask "who needs to do that?" Well, you could very well see that it opens up a whole vista of things you never even realized you couldn't do before. You can do it in other languages, but not nearly so easily.

INSERTED to answer Izkata comment:

  • The SHRDLU natural-language-understanding program worked by translating an English statement or question into a program in a Lisp dialect called MICRO-PLANNER and executing it.
  • Programs that manipulate programs, for example to simplify them or prove them correct are naturally written in Lisp.
  • I used program generation in a program to comprehend visual scenes, where it had to deal with all the symmetries capable in 3-dimensional objects, without multiplying the code.
  • Anything having to do with logic and theorem-proving deals in manipulating logical expressions, which are a form of program.
  • Symbolic math, such as symbolic integral or differential calculus, involves manipulating math expressions, which are like miniature programs.
  • Any problem involving code generation, or the more highbrow term "partial evaluation", is natural in Lisp. I did this for a database bridge program a long time ago. I did it in C, which was not as easy as Lisp, but I got the idea from Lisp. That was regarded as a technique that almost nobody could do at that time (especially the COBOL-heads). Maybe more now, I hope.

... that's just a few ...

Then you realize some things that are considered "modern" today have been old-hat in Lisp for 40-some years. Like functional programming. Like garbage collection. Like closures.

That's not to say modern languages don't have new good ideas, like OOP, etc. But if you learn Lisp it will broaden your perspective.

OTHER TIPS

The simple answer to your question is to try Lisp, preferably in conjunction with SICP. Then you will be enlightened.

That said...

Code is Data
Most languages make a sharp distinction between code and data; Lisp does not. This makes it possible to, for example, trivially write a Lisp parser in Lisp, and to manipulate Lisp code within Lisp. The best description of this enlightenment that I have found is The Nature of Lisp.

This is true in part because the syntax for the language is so simple. It makes possible things in Lisp (like metaprogramming) which are impractical in other languages because the syntax gets in the way.

Further Reading
Beating the Averages

Why is the study of an interpreter that is written in the language it interprets so emphasized?

In general, studying an interpreter gives you insight into its language and features. In general, studying code in a programming language is like practicing a spoken language by listening and reading: it familiarizes you with what that language can do, how it's used, and common "idioms". More specifically, Lisp is a homoiconic language, meaning its syntax for expressions is the same as its syntax for data. Writing code in Lisp looks awfully like you're writing out a list, and vice-versa. Thus, interpreting Lisp code with Lisp code is as simple as running through lists with car and cdr.

How should I capitalize on this exercise to get the most out of it conceptually?

Think about how the interpreter would interpret itself - in many meta-circular interpreter implementations (where a homoiconic language interprets itself) can just "pass through" the function. For example, To implement car, simply take the car of the argument. This takes the emphasis away from data storage mechanisms and focuses on functionality.

How do lisp interpreters demonstrate good architecture concepts for one's future software design?

Interpreters can be very complicated, which encourages good architecture in designing them. With that in mind, this one is more dependent on the individual interpreter.

What would I miss if I did this exercise in a different language like C++ or Java?

These languages aren't homoiconic, so they don't benefit from the grace and simplicity of a meta-circular Lisp interpreter. This makes the exercise harder, and perhaps less common, but I wouldn't say it's really any less beneficial.

What is the most used takeaway or "mental tool" from this exercise?

I'm not sure I have a good answer for this one; simply that it helps to see how the interpreter works and, maybe more importantly, tinker around with it to see how minor changes to the language can be easily implemented.

LISP is itself structured in a way which makes it extremely easy to parse. If you try to write a compiler, you will notice that it's a lot easier if everything in your language is an expression and has a low level of ambiguity. LISP forces parentheses everywhere to eliminate ambiguity and has no statements, only expressions.

The very fact that LISP is very easy to parse encourages users to parse their own source code and do magic tricks with it. The line between data and code becomes blurred and you can easily do things which normally require quite some effort, like reflection, dynamic code rewrite, plugins and serialization.

That's the gist of it. The exercise is probably meant to give you some insight into what is possible when the code is easily parseable from itself.

I'm not sure it is really important for everyone. You can be a successful developer without knowing how a Lisp interpreter works. When studying Computer Science, the basic ideas of Lisp should be learned though.

Lisp interpreters are important for Lisp programmers. They need to understand how an Interpreter ([and compiler]1) works, to fully understand how to use the language.

A Lisp interpreter is often used as a tool in computer science to teach students a few things:

As a teaching device, a Lisp interpreter is helpful, because it can be learned and understood in small time. Since few students already know about Lisp, the students are on a level field when it comes to learning above concepts.

Licensed under: CC-BY-SA with attribution
scroll top