Lisp newbie
Where do I start?

Q: What is the purpose of this page?
A1: Well I am one, and I have lots of questions. I was going to do the wiki thing of "braindump onto the page, then delete or refactor later". Hopefully CLiki could be left with a page which other newbies could use to get started.
A2: A repository for stupid questions that might otherwise be answered in part 1 of the FAQ.
A3: An editting area for questions to cull for the FAQ? I'm afraid I don't do Usenet any more, like I don't do TV. Just can't keep up with it.


Background on a newbie

My apologies to Larry Wall for jilting Perl (but see Cut and shut), but I think the next project requires something Lisp-flavoured, although I don't know what. The spec for the project changes whenever I contemplate it, see noosphere.org for something in the same vein.

I suspect my questions would be too far OffTopic for WardsWiki, so I trundled over here.

I've dabbled in elisp, but I need something that can live outside emacs (yes I know I can fire it up on the command line .. but that doesn't seem right).

"Emacs Lisp considered harmful" moved to the elisp page. That said, I would like to see one comparison page if such a beast could exist.

Naturally I'm after something that's already ported to Debian. Laziness and moral soundness in one easy to swallow package(ing system). *g*

Well, assuming you mean Debian on x86/Linux, you have the choice between CMUCL, SBCL, CLISP, gcl, ecl and installer packages for Allegro and LispWorks. I have most of them installed.

The problem

I'm circling the Lisp family like a vulture. I'm pretty sure it has what I need, but I'm not sure where to attack to get going efficiently.

The thorough route would be to read half a dozen books on Lisp, Scheme and Haskell, learn each, and then compare. However I'm an idle sod, so that doesn't fly.

Lisp or Scheme or ...?

I don't mean to start a fight here .. I suppose the only fair way to find out whether I want Lisp or Scheme is to try both, but that takes three times as long...

(See Wiki:LispSchemeDifferences for a start.)

Q: If I start with one and then decide to change to the other, how much trouble will I have? Can I just translate keywords and port to the different library, or would I need to start from scratch?

They really are completely different languages.

I'm getting that impression, but at this stage this is about as helpful as telling a Basic programmer that Java is completely different to C#. I'm trying to be objective about something I don't understand.

If you are viewing Lisp & Scheme from the vantage point of a Java/C++/C# programmer then they look awfully similar. A lot of the points on the early learning curve are similar - getting used to the syntax, the idea of closures, functions as parameters, s-expressions, macros rewriting code etc. It's only once you have peeled away this layer that you start noticing the differences, and that they are in fact quite different languages. I'm still pretty much a newbie, but the best way of expressing the difference by analogy seems to be comparing CL to C++, and Scheme to C. Sure, Scheme is smaller, easier to learn, more lightweight and has generally more implementations, so might be more suitable for the newbie aclimatising to the LISP family, but CL is a much more thoroghly thought - out language, with a much broader spec, more suitable for multi-paradigm programming in the large..

Q: What am I missing out on with CL? Does anyone actually use continuations? Without regret?

You can do continuation-passing-style without call/cc. The classes I've taken where we've used CPS never touched call/cc (though we did implement it).

Is the continuation done by arranging to return its value, or do you have a funky macro to redirect the execution path?

SchemeVsLisp: Scheme has Hygienic macros, which are supposed to stop you shooting yourself in the foot. The CL people tell me that sometimes you need to shoot something very close to your foot, and should be allowed to; and that when you don't, CL can restrict your macros in a similar way.

What's more, Scheme's hygienic macros don't actually stop you from shooting yourself in the foot. See postings in comp.lang.scheme by Al Petrovsky for mind-boggling uses of Scheme macros.

Q: Can I get the best of both worlds? (i.e. use CL libraries from Scheme). Well I did say "stupid questions".

In what sense is this the best of both worlds?

Common Lisp implementations

So many to choose from. Do I pick one that's beginner-friendly or just start with something that has convenient Database and Web hooks? Do I worry about performance now or when I'm firmly stuck with one implementation? etc.

Well, probably CLISP is the most "beginner friendly" (if there is such a thing) due to readline, but you can put readline around CMUCL too (look around this wiki). Convenient database and web hooks are available for all major LISPs. Web application too (Araneida, CL-HTTP, PortableAllegroserve). So, there you have it: I managed not to answer your question. ;)

Language features

Q: Is Lisp suitable for ExtremeProgramming or other agile processes?
A: It would seem that it is not only suitable, but they did it first. See Wiki:AgileLisp for example. Of course the language can't help you talk to your Customer, but it streamlines testing remarkably. So I'm told, but I can see it happening already.

Q: I like heredocs. How do I do them in Lisp?
A: You could probably cook up a funky reader-macro to do heredocs in lisp. Probably a good first exercise in reader-macro-land. Actually, Doug Hoyte implemented a working heredoc in his book Let Over Lambda

Q: What does the compiler do for me behind my back?

I started asking about this on WardsWiki, Wiki:WhyLisp but may bounce back over here to keep the topic police happy.

I've found disassemble now and I'm quite impressed. It's good to be able to get that close to whats going on, when you need to of course, and so easily too. I would consider this a selling point when pitching to a hacker.

Q: Hypothesis: If a function f is known to be pure, can I assume that the worst f can do if it turns out to be malicious is waste CPU and memory, until terminated?

It could return an eeevil data structure or maybe call a purely eeevil continuation.

Well naturally one doesn't trust the data it returns, but I'd forgotten about continuations. Surely it can only get one from a global or other callable function? Global variables would all have to be eliminated. 8-/

Q: How can I detect whether a function is pure? (I mean it's just data, right? But it refers to lots of other code, whose purity is unknown)

First, solve the halting problem. Then...

But really, who cares? This is Schemeish thinking, but CL isn't Scheme. You will probably end up writing code in all sorts of paradigms, eventually, and excessive worrying about making functions ``pure'' is a waste of time, often.

This would only be useful as applied to the previous question. I think instead perhaps it would be better to reimplement a subset of Lisp in Lisp but paying attention to security? Not that I need to do this yet, but the ability would fit the project I think I'm headed towards.

Don't wanna play with Java, but it would fit better in other respects.

Q: Is there a reverse list of functions and syntax? Something like a list of all functions (um, how many are there in CL?) mapped to related concepts, e.g. '(("joiners" cons list nconc append) ("splitters" car cdr nth))

I've got to the point where I think I need "something that does the opposite of list", and I'm not sure where to look.

Not sure what you mean here, are you thinking of DESTRUCTURING-BIND?

I don't quite follow it, but it sounds ilke the right sort of thing, although having looked at some list traversal examples I'm already seeing I was going down the wrong track anyway.

I think my interntion for this question has changed, sorry. It was a fuzzy Q anyway.

On the other hand, the HyperSpec, as well as having a page on everything, is organized into chapters... so you can read the Sequences chapter, or the Conditions chapter, and learn 'vertically' that way.

Q: Lisp advocates talk about the advantages of the Lisp environment in operating incrementally: fixing bugs and then retrying and continuing execution, making changes while your program is still running etc. This sounds way cool, but are there any documented examples of how to do this stuff, especially with CLisp or CMUCL?

A: For a simple "proof of concept," just start CLISP or CMUCL and define a function or two in the reader (as opposed to writing them in a file and then loading the file). As you see, you can test the functions, redefine them, debug them, etc. It is much more pleasant, of course, to write code in an editor, so your next step should be to hook up a Lisp to Emacs. ILISP is a popular package that works with most Lisps. ELI is, IMHO, much better, but doesn't work with other Lisps than Franz's Allegro CL out of the box. (There are patches and hacks that make it work with other Lisps, though.) If setting up ILISP or ELI is too much work for you, you can download the demo version of Lispworks, as it has an integrated editor.

Slime is the preferred Lisp environment these days (June '04).

Once you have your Lisp hooked up to an editor, you can edit a file full of code in an editor buffer and press some special key each time you change a definition (such as a DEFUN). The code you changed will be automatically sent to your Lisp and compiled. (There will also be a reader available, which is nice for one-liners you don't intend to keep.)

Q: I've also heard about hitting a bug and being able to make a change to the code and resume execution (the sort of thing you can only dream about in Java). How do we do this?

This is slightly implementation- and problem-dependent. Here's a very simple example, from SBCL:
* (defun fact (x) (when (> x 0) (* x (fact (1- x))))) ; factorial function

FACT
* (fact 5) ; test it.  Oh look, it's buggy!

debugger invoked on condition of type SIMPLE-TYPE-ERROR in thread 16927:
  Argument Y is not a NUMBER: NIL

restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT   ] Reduce debugger level (leaving debugger, returning to toplevel).
  1: [TOPLEVEL] Restart at toplevel READ/EVAL/PRINT loop.
(SB-KERNEL:TWO-ARG-* 2 1 NIL)[:EXTERNAL]
0] (defun fact (x) (if (> x 0) (* x (fact (1- x))) 1)) ; fix the function

STYLE-WARNING: redefining FACT in DEFUN
FACT
0] f 1 ; go down a frame to somewhere where we know the answer
(FACT 1)
1] ret 1 ; return 1 from the current frame (1! is of course 1)

120 ; the right answer to our original problem

Bear in mind that this was a very simple example.

Q: In the incremental style of development, if I make a new function with (defun ....) and do lots of typing, and it finally all works, how do I then get that into the "source code"? Do I have to scroll back to what I typed and copy and paste it into a file? I understand that I can save an image file, but that's not source code.

A: Most of the time, you probably won't be typing your defuns at the REPL; instead, most people tend to use something like SLIME or ILISP, which enables communication between an Emacs and your Lisp. This way, you type your defuns in a real editor, complete with good line editing functions and all the Emacs sexpr navigation goodness, and when done type control-meta-x to send the form to your Lisp.

Also, you ought to consider writing your code in files and invoking compile-file on them (in SLIME, control-c control-k does this in one step). This is still interactive development - even though your code is stored in a file and compiled, you can still send new definitions via control-meta-x as you test and debug, and the REPL is still available for you to test your definitions out.

Q: Where do I get information on Gray Stream?

Useful links

- An ECL + Qt4 Windows/Linux example ; this one is newer (requires CFFI, works with many recent Lisps)

On Flaming

Newbies are friends, not food!