Lisp programming questions

For one reason or another I’ve developed an interest in Lisp in the last few days. But I’m having a hard time finding the very basic info I’m looking for. I know there are currently 2 lisps in general use - Scheme & Common Lisp. I’d like to know more about both.

  1. Is lisp code compiled like C, or is it interpreted like Perl, or strange mix like Java?

  2. Are there any good free lisp IDE+compilers similar to Bloodshed Dev C++?

  3. It seems lisp is used heavily in AI research - why? What in particular makes lisp more suitable than (say) C for AI programming?

  4. What else is lisp well-suited for, what is it not well suited for, and why?

I realize the last 2 may be more IMHO questions, so I’ll be happy with industry-standard type answers & links to arguments for or against those answers, to keep it factual.

Thanks very much!

I know a bit of Lisp and Scheme and know some other functional languages fairly well.

Scheme is designed to be elegant whereas Common Lisp is designed as a general purpose programming language. I prefered Scheme when I tried them, although you may differ.

Depends on the compiler / IDE. I’m pretty certain that some commercial compilers can produce executables. Programming in Lisp and other functional languages isn’t like programming in C, due to the interactive top level. There’s really nothing like it outside declarative languages.

Dr. Scheme is a good environment for learning Scheme. It’s easy to find on Google.

Code is data and data is code. Lisp’s abstract syntax tree is available to the programmer to meddle with through macros, which make it very easy to modify the language as you go along. Not only that, but functional and logic languages in general are very popular in AI research, due to a few of them being offsprings of that research (Standard ML came out of theorem proving research, for instance).

Common Lisp is a general purpose programming language that can be used for anything that you would use Java for. Scheme is generally aimed more as a teaching language and has a focus on elegance and simplicity.

Lisp is also dynamically typed. If you’re used to Java and other statically typed languages, this may be a bit of a shock. If you wish to keep with statically, strongly typed languages but wish to learn functional programming, then Haskell, Standard ML and O’Caml are good choices.

Note, if you’ve never done functional programming before it’s a lot different to imperative programming.

HTH.

Different implementations do things differently, but Allegro Common Lisp can be compiled. Also, be aware: Scheme isn’t quite a Lisp. There’s a (large) document called the Hyperspec that defines all the things a language has to do to count as a Lisp, and Scheme doesn’t do all of them. With that said, they’re very similar languages and the differences are pretty small.

The demo version of Allegro may suit you. Other free implementations include CLISP and CMUCL.

There isn’t a universally accepted factual answer to this - some AI programming is done in C. The standard Lisp-advocate answer is that Lisp makes you put up with less crap than a middle-level-language like C. There’s no way to use a stale pointer, it’s very difficult to generate a memory leak, etc. Also, with syntactic macros you can invent language constructs appropriate to the problem.

Again, the standard Lisp-advocate answer is that Lisp is well-suited to hard problems that aren’t basically math. There wouldn’t be a lot of point to writing graphics code in Lisp, for instance; it’d be faster in C and the Lisp code wouldn’t be significantly more elegant or flexible. On the other hand, audio processing is basically math and Nyquist is scripted in XLisp.

You may find it worthwhile to browse through the archives of comp.lang.lisp, which is very active and where this issue comes up regularly, with vociferous argument on both sides.

Scheme is not Lisp. Lisp is flawed, as admitted by its creator John McCarthy (damn – now I can’t find a cite). IIRC, it has to do with the theoretical underpinnings of Church’s lambda calculus, which Scheme follows more rigorously.

You might want to take a gander at the Wikipedia Common Lisp page; they’ve got a list of available packages there.

First, Lisp was the second (high-level) programming language in existence (FORTRAN being first, both well before C). Second, it makes heavy use of recursive programming, which some argue is a natural expression (or even a prerequisite) of intelligence. Third, as mentioned above, Lisp is founded on Church’s lambda calculus, which can describe any computable function in a clean and concise way.

It is well suited for rapid prototyping. It is unsuitable for use by many programmers (perhaps the majority?) because they’re just not all that good with non-procedural languages (myself included).

Much of the above is just off the top of my head; corrections and clarification are welcome…

The above answers are all good. However, if you’re interested in functional programming, you might want to check out Haskell instead. Unlike Lisp, it has a syntax that won’t drive you insane, and most functional programming research is being done in Haskell these days.

The emacs editor (available on every platform) uses LISP as its scripting language. I’m not sure if the editor itself is written in LISP though.

And if you can’t stand monads, use SML :stuck_out_tongue:

Emacs itself is written in C, although almost all the functionality is implimented as extensions in Emacs Lisp.

I’m still trying to figure out the CAR of the COOTER…

Carry on…

Which means you don’t get macros, one of the real benefits of Lisps. (No, C and C++ programmers, you have no idea what macros are unless you’ve also used a Lisp at some point. Just because something is called a macro doesn’t mean it really is one.)

This page, a chapter from a book that teaches Common Lisp, addresses some objections to Lisps in general. Most of the objections are either wrong, outdated, or simply founded on ignorance.

The best way to learn Lisp (Common Lisp in specific, probably the only ‘standalone’* Lisp worth learning at this point) is by reading Practical Common Lisp by Peter Seibel. It includes links to software (not the least of which is Emacs, which, as has been said, is also a Lisp system.) and generally gets you all set up and ready to develop interesting software, as opposed to the more theoretical approaches Lisp texts sometimes take.

*(‘Standalone’ as in ‘not the extension language of a specific application’. The two other interesting Lisps are Emacs Lisp, the extension language of Emacs, and AutoLisp, the extension language of AutoCAD. Extension languages are fine and useful things but very constrained by the fact that they can’t produce standalone programs.)

Once you have worked your way through the book above, you’ll want some reference material. Common Lisp is a large language, both in terms of the standard library and in terms of the programming concepts explicitly supported. The easiest to navigate is by far the Common Lisp HyperSpec, while the easiest to grab and just read is Common Lisp the Language, Second Edition by Guy L. Steele. Both complement each other and both have their use.

I think the link orgy for this post is pretty much over. :wink:

Perl is a strange mix like Java, as a matter of fact. :wink: The term you’re looking for is ‘byte-compiled’, and many Lisp implementations do go that route. Many Lisp implementations also compile to machine code, at least as an option. A lot of Lisp development is done at the REPL (Read-Evaluate-Print-Loop, the top-level command interpreter that accepts Lisp forms and prints their results) but not all of it.

I like Emacs plus the Slime package, as offered at the Practical Common Lisp website. Your tastes may differ, but remember that Lisp is a fundamentally different language from C++ and requires different tools. As Gandhi said, bloodshed isn’t always the answer. :wink:

For one thing, Lisp is garbage-collected. This means that, unlike in C, objects are created and reclaimed automatically, so there is no chance of a buffer overrun or a memory leak. This alone puts Lisp well ahead of C when speed and memory use aren’t top concerns.

For another thing, Lisp allows you to write the language you really need to use to solve the problem at hand. When you give a person C (or FORTRAN, as this chestnut originally ran), C is all he has. When you give a person Lisp, he has any language he wants. Macros play a huge role in this language-building aspect of Lisp.

(Which reminds me of another book, On Lisp, by Paul Graham. This book also teaches Common Lisp, but it focuses explicitly on the bottom-up, macro-heavy style that gives the language much of its strength.)

Lisp is good at exploratory programming, when you don’t know the problem domain very well and want to create a solution it’s very easy to modify as you learn by doing. It’s good at letting you ignore the specifics of data representation (strings are strings, not arrays of bytes, numbers are numbers, not ints, longs, and floats, etc.) and focus on the specifics of algorithm representation.

It’s bad at allowing you to write fast programs unless you know what you’re doing.* You can use declarations and a somewhat odd programming style to write code nearly as fast as, if not faster than, an equivalent program written in C, but usually you don’t have any reason to do that. It’s bad at allowing you to finely control memory usage, due to the complexities of garbage collection. You’d never write an OS in Lisp for many of the same reasons you’d never write an OS in Java.

*(On the other hand, C is good at allowing you to write fast programs but it’s bad at allowing you to write correct programs unless you really know what you’re doing. ;))

Lisp is also bad at allowing you to interface with external libraries. The foreign function interface isn’t as easy as it is in C, for example, or in Perl.

This is more-or-less nonsense. Scheme is Lisp by any reasonable definition, and they both follow the lambda calculus to the extent that it is actually practical to do so. Scheme probably deviates from the lambda calculus more than Common Lisp does, because Scheme has first-class continuations.

Finally, of course Lisp is flawed. Java is even more flawed, and C++ is more flawed still. Picking the right language is, to a large extent, finding the flaws you can live with.

Please do not tell me what I do and do not “get.” Believe it or not, a person can be quite versed in functional programming in general and Lisp in particular and still prefer solutions that do not, as one famous programmer put it, resemble fingernails in oatmeal.

FWIW, Haskell has excellent support for metaprogramming as well (and so does Perl for that matter. Hell, even Javascript has lexical closures.)

But that’s all besides the point. If one wants to learn Lisp, then learn Lisp. It does really cool stuff. But all technologies have their dogmatic adherants, and it’s important to make decisions about what to use based on objective analysis of the technology, not zealots who shout that people who prefer other solutions don’t “get it.”

Now, now, no reason to get touchy. When I say “flawed”, I mean theoretically. IIRC – and again, I don’t remember where I saw the McCarthy quote – he admitted that he made a mistake in the conceptual formulation of Lisp, and one that Scheme addressed. Searching my memory, I believe it had to do with the defun construct. That’s all – I’m not slandering the Lisp class of languages.

Now, practically speaking – yes, there’s not much difference and they can be considered dialects of the same language. Furthermore, I’m not heavily into programming language theory, which is why I welcome any corrections and/or clarifications. Functional languages are fascinating beasts, IMO, and I’m rather sorry that my exposure to them has been relatively minimal.

Macros and functional programming are orthagonal, though. You could have a Lisp-like without first-class functions (it wouldn’t be CL as the standard defines it, of course), but it’s the “fingernails in oatmeal” syntax that makes syntactic macrology possible. Strong macros are the one thing that Lisp has and no other language really does; Dylan and Python have both tried to use syntactic macros effectively in an infix style, but the result was a language feature that no one but a wizard could safely use.

Wow, just when I think I know something…I’ve been 'in the industry" for 12 years, and had never heard of functional vs imperative programming. I just thought it was all programming.

Guess I’ve got some reading to do!

Then you can learn Prolog after that for a bit of logic programming :smiley:

Once you learn functional programming, you’ll never like using Java / C++ again (at least I don’t).

I meant get as in receive, not get as in comprehend. You don’t get macros with Haskell because the standard language doesn’t specify any macro system.

Which is true.

Which is touchiness (q.v. Digital Stimulus, above). :wink:

Glad to see you didn’t take that the wrong way. The last thing I want to do is to get into a “vi vs. emacs”-type debate about languages; they’re all interesting (admittedly, some more than others, and functional languages more than most). :slight_smile:

Well, yeah. But Emacs is better!
:stuck_out_tongue:

Since this is GQ – and a Lisp thread – I’ll let that one die a (hopefully painful) death and say no more about it. :smiley:

Because I can’t leave well enough alone…

The real reason you don’t get macros with Haskell is because it’s difficult to implement a good, easy-to-use macro system in any language that has syntax. Lisps don’t have syntax, which leads to programs that look like fingernails in oatmeal but gives the programmer an up-close and personal look at the abstract syntax tree (AST).

The AST is what all code is turned into by the parser before the interpreter, byte-compiler, optimizer, or machine-code generator gets a hold of it. It represents what the code really says, as opposed to what the code looks like on the screen. A macro is a small program that turns one AST into another according to rules laid down by the programmer. Since in Lisp programmers are working with trees all the time anyway, it’s trivial for them to visualize how to transform one AST into another using the tools they already have. (The traditional glossing of Lisp as a list processing language is somewhat misleading. In Lisp, a ‘list’ is really a tree written with nested parenthesis (like this) instead of circles and lines.)

This is the most important consequence of the homoiconicity of Lisp, the fact that programs look and work exactly like data. It doesn’t lead to ‘pretty’ code in the traditional sense, but it does lead to very useful code.

“What Made Lisp Different” by Paul Graham says some of the same things and plenty of other important things.