Talk:Lisp (programming language)/Archive 1

Page contents not supported in other languages.
From Wikipedia, the free encyclopedia

Oldest programming language

"The language is still in use in 2001 and is therefore the oldest programming language still currently in use (as of writing in 2001)."

Actually Fortran is older by about 2 years, and is still in serious use. Not many (if any) modern Fortran programs are actually compatible with the original version of Fortran, but that is probably true for LISP as well.

Cobol is still used to some extent and is about the same age as LISP. I could probably be talked into believing LISP is a few months older.

There may be a few ALGOL programs still out there doing useful work in some obscure part of Europe, and again, ALGOL is about the same age as LISP, perhaps slightly older.


Yes, I deliberately stuck my neck out on that one. It did cause me to go and do some research though. You didn't even attempt to back up your Fortran claim but it appears to be true! --drj


Typo

CAR (Contents of

Address Register) and CDR (Contents of Address Register) are the operations for returning the head and tail of a list respectively.


Do CAR and CDR really stand for the same thing? (I don't know much about list, having read something about it in a Sci. Am. article about it over a decade ago, and not much since) -- dja



No, CDR stands for Contents of Data Register. Typo/thinko. Fixed. Ta. --drj

Lisp example

Function CAR in LISP program returns the first element in a list.

  (car '(a b c d))
  Returns a

Function CDR would return everything but the first element in a list.

  (cdr '(a b c d))
  returns (b c d)

There are of course many variations of this.

  (cadr '(a b c d))
  Returns b

Working from the inside out is the same as (car (cdr '(a b c d)))


Missing joke/criticism

I would insist to reintroduce "Lot of Insane and Stupid Parenthesis" somewhere this is a famous joke and has also its place in Wikipedia. --Ericd 20:27 Apr 14, 2003 (UTC)

It is in there. Paragraph 2 of "Syntax". It's "Lots of Irritating Superfluous Parentheses", btw (sometimes also "Lots of Isolated Silly Parenthesis".) --CYD


Renaming

I propose that this page should be entitled Lisp programming language for two reasons: First, the spelling "LISP" (in capitals) does not seem to be used among current practitioners of the language. (See for instance the newsgroup comp.lang.lisp and the work of Paul Graham.) Second, this will bring it in line with the other pages of the form "Name programming language" while preserving distinction from the word for the speech impediment. --FOo 00:40 7 Jun 2003 (UTC)

I don't think we need programming language. In fact, many articles have no programming language suffix. Take Fortran, C Plus Plus and so on. --Taku 00:47 7 Jun 2003 (UTC)
Hmm. LISP is its proper name, and since it's an acronym, it seems to me more appropriate to keep it in caps. Perl, for example, is in lowercase, since it was backronymed, and is not really supposed to be in caps. COBOL remains uppercase, without the "programming language" suffix. Fortran has no suffix either. Convention seems to say leave it as is... --Wapcaplet 00:58 7 Jun 2003 (UTC)
"LISP" is long-obsolete; look at 2nd edition Common Lisp the Language from 1990 for instance, it's always spelled "Lisp", in contrast to 1st ed., which used small caps. I'd personally prefer Lisp (programming language) because someday we might have spiffy software that filters ()-disambiguators in article headings and such, but Lisp programming language is OK too. --Stan 01:12 7 Jun 2003 (UTC)
There already is such a thing: the magic piping trick. For example, typing [[spin (physics)|]] gives you spin. Unlike the names of other programming languages, Lisp has another meaning, i.e. a speech defect. Therefore, the article should be named Lisp (programming language). --CYD
Since there is an obvious ambiguity, I have no objection to rename this to Lisp programming language. Please don't use (programming language) because that style is not used usually. --Taku 01:53 7 Jun 2003 (UTC)
According to the convention about naming programming language, we don't put pre-diambiguation programming language. It is debatable but there is an agreement that seems reached. I am not sure which one, LISP or Lisp. To me LISP sounds rather antiquated but I am not sure. --Taku 01:19 7 Jun 2003 (UTC)
To me, spelling it "LISP" reeks of either a botched transliteration from small-caps (as with "UNIX", see the jargon file) or a usage on all-caps terminals or filesystems. Bleah. I recognize the "Foo programming language" (rather than "Foo (programming language)") convention for languages whose names have another meaning (like Python, C, and Lisp, and unlike Fortran) --FOo 03:55 7 Jun 2003 (UTC)
I agree that this should be moved to "Lisp programming language". The lower case form is much more common. --Minesweeper 17:33 7 Jun 2003 (UTC)
(Followup: the article was indeed moved to 'Lisp programming language'.)


Unicode

Which variants of Lisp have native Unicode support? --Hirzel

Unicode and Lisp --Taku 02:17 12 Jun 2003 (UTC)
Thank you for the answer! --Hirzel


Bootstrapping Lisp

The article says:

A minimal Lisp needs just a few functions implemented in C or machine language.

   * car
   * cdr
   * cons
   * quote
   * eq
   * cond
   * a mechanism to define functions 

Is there an open source C (or Pascal, Basic or whatever implementation) which shows how this is done? A lisp version is found here (use link McCarthy's original implemenation) --Hirzel 08:08 1 Jul 2003 (UTC)

Is "cond" really necessary? I think if you define "true" and "false" appropriately, you could implement cond. Also, is it possible to implement gt and lt if you only have eq?
Yes. You need some means of making a branch, or conditional statement -- either cond or if can provide this. As for eq, it is not used for arithmetical equality, but rather for determining whether two symbols are the same. Arithmetic doesn't enter into it -- this is a minimal set of operations for list and program-code manipulation, not for arithmetic. Anyhow, arithmetic can be implemented (slowly!) in terms of lists or functions, as by using a W-representation or Church integers. --FOo 15:04, 7 Aug 2003 (UTC)
Forgive my notation, but True can be defined as "\ x . x" and False as "\ x ." where "\" is lambda. Then cond would be unnecessary because True and False would take care of it. Of course, if you're using eager evaluation, this isn't quite true, because "(False foo)" will still evaluate foo (which doesn't matter if it's referentially transparent). --Doradus 15:15, 7 Aug 2003 (UTC)
It wouldn't be Lisp anymore then; "cond" is the fundamental conditional construct shared by all Lisp versions. --Stan 16:10, 7 Aug 2003 (UTC)
Have a little imagination. If I can get the effect of "cond" using lambda calculus, I'm sure someone smarter than me can get the syntax in a similar fashion. Lambda calculus is Turing-equivalent on its own, and doesn't need a "cond" primitive to get that way. --Doradus 11:27, 8 Aug 2003 (UTC)
The problem is, we are using eager evaluation, and it's not referentially transparent. You need at least one form that doesn't evaluate all of it's arguments..
This is an article on Lisp, not alternate possibilities for Lisp-like languages. The purpose of the encyclopedia is to describe things as they are, not as they could be, unless the hypothetical somehow elucidates. For instance, one could make a comment that "cond is not strictly necessary under some evaluation regimes" or some such, and in fact there is an interesting little bit of history about how these particular primitives came to be chosen. --Stan 13:45, 8 Aug 2003 (UTC)
It wouldn't be Lisp since Lisp cond and if are defined as having conditional evaluation of arguments. For that matter, it should be theoretically possible to make a Lisp system solely out of NAND gates (including flip-flops for memory), but that does not mean that NAND constitutes a Lisp system. --FOo 14:03, 8 Aug 2003 (UTC)
I'm sorry, I must not understand what you mean by "minimal" then. If I can implement cond using elements that are already in the language, then I don't need cond, right? I'm almost certain I could define cond in terms of "a mechanism to define functions" (ie. lambda calculus), making it redundant in a minimal Lisp. If you really don't believe me, I'll take the time to actually do this, though I'm not a lambda calculus expert, so it will take some effort. If it's just the concept of "minimal" that we disagree on, then that may be easier to resolve. --Doradus 15:15, 8 Aug 2003 (UTC)
If you dropped any of these functions, a Lisp programmer would say "this isn't Lisp anymore", so "minimal" is the right word. It doesn't matter what lambda calculus is capable of (by that standard, car/cdr/cons aren't necessary either), because this is about Lisp the language as it is normally understood. If you want to write about some other language that looks like Lisp but has fewer primitives, publish an article about it in Dr. Dobbs and then we'll reference it here. --Stan 15:31, 8 Aug 2003 (UTC)
If Doradus can implement cond using lambda calculus, including the syntax, his objections would be valid. However, I don't see how to do that off the top of my head, and it may not be possible. --CYD
Ok Stan, I think I see where you are coming from. Whether cond is defined by lambda calculus, or is provided as a primitive, the fact remains that it must be defined somehow in any language that claims to be Lisp. So I yield. :-)
Incidentally, CYD, do you think a Turing machine could implement an interpreter for cond, including the syntax? If so, lambda calculus can do it too, because lambda calculus is Turing-equivalent. --Doradus 03:48, 9 Aug 2003 (UTC)
My point is that it is probably syntactically impossible, since cond uses some special syntactic rules that are treated specially by the Lisp interpreter. In other words, you'd have a problem getting the input into your "Turing machine" without encountering an interpreter error. Of course, I'd be happy to agree that you were correct if you can show us how to implement cond with lambda. --CYD

Are you talking about the fact that cond is variadic? Besides that, and keeping in mind that I don't know Lisp, how's this...

(defun true (y n) (y))
(defun false(y n) (n))
(defun cond(x) x)

In other words, with the right definitions of true and false, cond is a no-op. Or, if you don't like that one, there's this:

(defun cond(x) x)(
    (ys eq ()) (n)          -- If there are no predicated expression, return the "else"
    (
        (caar ys) (cadr ys) -- If the first predicate is true, return its expression
        (cond (cdr ys) n)   -- Otherwise recurse without the first predicated expression
    )
)

This assumes eq returns either true or false as defined above. -- Doradus 15:24, 24 Aug 2003 (UTC)

What I mean is this. Suppose you attempt to define cond in the following way:
(defun cond (x) blahblahblah)
where blahblahblah stands for whatever you need to do with the argument x to get cond to work properly. However cunningly you attempt define this function, it would not be able to handle, e.g.,
(cond (misc-variable-name 1))
This is because, since cond is defined as a normal Lisp function, the Lisp interpreter attempts to evaluate (misc-variable-name 1). This is a no-op, because misc-variable-name is not the name of a function. That's why cond is called a "special form" - its syntax is handled specially by the interpreter. --CYD
It works just fine if "true" and "false" have the definitions I gave. --Doradus 11:20, 25 Aug 2003 (UTC)
No it doesn't. For your reference, here is Emacs' online documentation for cond:
cond is a special form.
(cond CLAUSES...)
Try each clause until one succeeds. Each clause looks like (CONDITION BODY...). CONDITION is evaluated and, if the value is non-nil, this clause succeeds: then the expressions in BODY are evaluated and the last one's value is the value of the cond-form. If no clause succeeds, cond returns nil. If a clause has one element, as in (CONDITION), CONDITION's value if non-nil is returned from the cond-form.
In particular, CONDITION need not be "true" or "false", it can be any symbol. A arbitrary symbol need not be the name of a function, in which case (CONDITION BODY...) can not be evaluated. This can be proven by experiment in a Lisp environment. (The code you provided cannot be evaluated, btw.)
This debate is getting a little long, and inappropriate for Wikipedia. Why don't you take this to comp.lang.lisp? --CYD
True. I still think you're being a bit pedantic, and that the correction---from what I have given to a full-fledged bona fide cond written in lisp---would not be hard for a real lisp programmer. However, since I am not a real lisp programmer, and I don't intend to become one just to settle this argument, I suppose now is the time to call it quits. --Doradus 00:39, 27 Aug 2003 (UTC)
I am a Lisp programmer, so I'll chime in for posterity. Were cond to be removed from the above , there would be no branching construct. Consider the code: (cond ((= x 0) 0) (t (/ 1 x))). If cond were implemented as you propose, then the code (/ 1 x) would always be evaluated, even if x were 0. cond could be replaced in the above list by either if, or both and & or (which are short-circuit evaluators). But you gotta have a primitive branching branching construct, something that prevents evaluation. Also, note that the foregoing discussion about primitives did take place on comp.lang.lisp a year or so ago. --Piquan 10:27, 11 Feb 2004 (UTC)

Pro and Con (That is, criticism) sections

I'm considering adding a section listing the arguments put forth by proponents and opponents of Lisp. Would this be useful, or would it probably just spark a flamefest? --Piquan 10:29, 11 Feb 2004 (UTC)

Such a section would be useful, and there won't be a flamefest if the section describes the arguments, and stays scrupulously clear of trying to endorse any. If I can't tell from reading it whether you personally like or hate Lisp, then the material is properly neutral. --Stan 14:58, 11 Feb 2004 (UTC)


Indenting

I took the small liberty of adjusting the indentation on some code examples involving if. There's a nearly standard style of indentation for Lisp given in Steele's Common Lisp the Language, and it is unfortunate that GNU Emacs's default Lisp indentation violates this (when using the common-lisp-indent-function it behaves properly). The problem is that normally both the true and false clauses of if are supposed to be indented to the same level, but in GNU Emacs it outdents the false clause two spaces. Since this is entirely irregular (and not even that common in Emacs Lisp) I've made the change to the indentation to bring it in line with what is found in most other Lisp languages like CL, Scheme, etc. --James


Lisp "popularity contests"?

Does anyone know of any statistics about the number of users of different Lisps? I'd like to know such things as:

  • Are there more CL-ers or more Schemers?
  • Which Scheme is the most popular?
  • How many people use CL vs. how many people use the most popular Scheme?

--Ryguasu 19:02, 6 May 2004 (UTC)

I've removed this section for discussion. Despite the conversation above, it really isn't clear to me what was originally meant by it, and it's been pointed out as misleading. --FOo 00:06, 8 Jul 2004 (UTC)


A minimal Lisp

A minimal Lisp needs just a few functions implemented in an underlying language (such as machine language, or C on Unix systems):

  • car -- given a pair, return the first element;
  • cdr -- given a pair, return the second element;
  • cons -- construct a new pair with given first and second elements;
  • quote -- denote an expression as literal, not to be interpreted;
  • eq -- compare two objects for equality, returning true or false values;
  • if or cond -- a single- or multiple-condition branch operation; and
  • some mechanism to define functions, such as Common Lisp's defun, or else lambda and Scheme's define.

All the other functions may be implemented in terms of these -- albeit not very efficiently. Actual Lisp systems implement a much larger set of functions than this.

[Bogus misinformation above. Given only these functions, you cannot even lexically scan a parenthesized expression, never mind evaluate it and print it. You have no symbol table management, no numeric tower, no string handlnig, nothing.]
It's accurate in the sense that this is sufficient for Turing equivalence, and therefore sufficient for any computation. Of course, if you want to interact with special hardware, such as a keyboard that returns a stream of characters, you'll need additional functions, just as you would in C if you wanted to get frames from an attached video camera. This section was perfectly fine in the article. --Stan 05:16, 8 Jul 2004 (UTC)
I think most people familiar with it would say that READ and PRINT are as much a part of a Lisp system as EVAL is. An evaluator is not the same thing as a language implementation after all. What's more, the section above has misled readers (see the Usenet discussion rooted at this post) into thinking that such Turing tar-pits have something to do with the workings of actual Lisp systems. --FOo 13:38, 8 Jul 2004 (UTC)
The right answer is then to explain what "minimal Lisp" means, not to delete the section. Practical implementations will likely have some sort of I/O support. As someone who has actually taught Lisp to students, I can say that the concept of a minimal Lisp is very useful in clarifying what has to be primitive and what doesn't, and that students get the distinction between primitives and hardware support if you actually mention the distinction. --Stan 16:56, 8 Jul 2004 (UTC)
"Minimal Lisp" refers to the minimal set of functions in Lisp that can not be defined in terms of other functions in that set. --Anonymous


Address or Arithmetic?

In one place in this article it says that the A in CAR stands for Address, and in another it says that it stands for Arithmetic. I've more often seen "Address". Can someone who knows definitively fix the article? --Lkesteloot 03:57, 6 Oct 2004 (UTC)

It's 'address', as attested by McCarthy in HOPL. I'll fix. --Stan 06:25, 6 Oct 2004 (UTC)
Done. Incidentally, IBM 704 also names all the fields of its words. Always nice to know that one's restaurant is worth eating in! :-) --Stan 06:43, 6 Oct 2004 (UTC)
Thanks! (I think "decrement" is a weird term to use for that field.) --Lkesteloot 02:32, 8 Oct 2004 (UTC)
The above is not precisely right: it was apparently "Contents of Address part of Register" and likewise the decrement part. The register structure of this system is truly bizarre by today's standards, but here's the story: [1] --FOo 04:18, 8 Oct 2004 (UTC)
They meant "part", but didn't necessarily say it that way. The terminology of ancient times is often confusing by today's standards. --Stan 05:02, 8 Oct 2004 (UTC)
I am 99% certain the terminology was precisely this: "Contents of Address Register" and "Contents of Decrement Register". I am a live former LISP programmer who studied and used LISP at MIT and BBN in the 1970s, so I am changing the page to reflect this terminology. - Rlw (Talk) 00:34, May 30, 2005 (UTC)

Dylan

While S-expressions are almost universally a sign of a Lisp, not all Lisps have sexp based syntax. The most notable member of this group is Dylan.

Note that Dylan did have S-expressions for a while, but the syntax was modified in later revs of the language. Other examples of Lisp languages which have non-S-expression syntax are A-language, LISP 2, EL1, CLISP (not the modern implementation of CL, but "Conversational LISP" implemented in Interlisp using DWIM functionality), MLISP, and CGOL. See Gabriel and Steele's article The Evolution of Lisp for details on these "Algol-style" syntax alternatives for Lisp, and some cogent argumentation for why they never caught on in the Lisp world. — Ts'éiyoosh 00:15, 14 Apr 2005 (UTC)


Shared structure

Please remove the whole "Shared structure" section. It's completely false, as demonstrated in c2-wiki-style!! [Which is inappropriate on Wikipedia in my experience] Thank you. --80.98.243.176 03:08, 6 Dec 2004 (UTC)

Smells to me like you're trolling. But just in case -- your line (setq foo (list 'a 'b 'goose)) is where the problem is. The idea is to replace part of the structure of foo, not to replace foo. (setf (third foo) 'goose) would do it. --FOo 03:57, 6 Dec 2004 (UTC)


Second Oldest?

Lisp is described as being the second-oldest high level programming language in widespread use today, only Fortran being older. It seems to me that COBOL could be considered older on two grounds: 1) it came into being as an actual programming language before Lisp did, and 2) its basis (FLO-MATIC) predates even the paper Lisp was based on. --Anonymous

I'm not sure. It is pretty clear that Lisp, Fortran, and COBOL are all very close in age. However, the different ways in which they were developed (academic experimentation vs. formal specification) make it hard to compare exact dates. At what point is it meaningful to say that a language comes into being -- when it is specified? When it is implemented? When the specification is published? When it is deployed for "real world" use? This is unclear.
(One hackish definition of a "real language" (as opposed to "toy language") is one that has been used to write its own compiler. That would rather favor Lisp unfairly. [2])
The first COBOL specification was released in late 1959 according to our COBOL article, and it was published in January 1960. Steve Russell wrote the first Lisp interpreter in early 1959 according to him (see section "Email from Steve Russell"). Although McCarthy's article was not published until 1960, apparently there were already running Lisp systems on the IBM 704 before that.
I do not know when the first COBOL implementations were. There's an ACM paper cited in the COBOL article which might be enlightening, but I don't have access to it. Do you? My impression was that COBOL was the sort of thing that was specified first and then implemented -- whereas Lisp was described informally (1958), implemented ("early 1959"), and then at long last published about (1960).
Yet another factor is standardization. COBOL, like Fortran, was designed as a standard. Lisp was not -- it jes' grew. Formal Lisp standardization did not arrive until the publication of the Scheme report in 1978 or the ANSI Common Lisp standard in 1994! This latter date is well after there were already many successful commercial deployments of Lisp-family systems. If we go by the date of standards publication, we get a Lisp which is "created" after C and Unix, which would be a little baffling.
So I don't have an answer. Sorry. :)
Regarding your second point ... COBOL seems to have been a distinct system from FLOW-MATIC (sp?), and our COBOL article mentions at least one other language (COMTRAN) as an ancestor. The history of programming langauges is incredibly complicated, as can be expected, with ideas from all over influencing the creators of new languages. I think COBOL should be counted as a separate language from FLOW-MATIC, just as C is not considered to be the same language as BCPL. --FOo 00:24, 14 Apr 2005 (UTC)
I think it would be wise to point out that most people who deal with computing history call Lisp the second oldest language, whether or not this is actually true. So perhaps saying "Computing historians describe Lisp as the second-oldest language still in widespread use, second only to Fortran." That would be fair, and wouldn't require outlining the history debate which is off topic in this article. — Ts'éiyoosh 23:14, 15 Apr 2005 (UTC)
I am surprised to hear that. When I was taught taught at university, Algol was the second oldest programming language. I assume labeling Lisp the second oldest is part of a tradition of its own, maybe nit an informed tradition. Algol was also conceived in 1958, and there was much more publicity about it. --Anonymous
Is Algol still in use? I think that was the relevant qualifier. --Maru 21:37, 9 August 2005 (UTC)
It is indeed a relevant qualifier. Lisp and Fortran are both still in active use and development, and there exist actively supported proprietary and open-source versions of both. I do not believe any of these are true of Algol. --FOo 23:28, 9 August 2005 (UTC)
The last time it was discussed on usenet, Algol68 was still in use at some places in Britain and Russia. In the meantime, open source implementations of Algol68 have appeared. See the wiki entry. So, Algol is still alive. For a related matter, if only Scheme was around, Lisp would be said to be still alive. And the majority of the existing programming languages are just dialects of Algol. This fact is clouded by misnaming Algol-like languages Pascal-like languages.
And the majority of the existing programming languages are just dialects of Algol. This fact is clouded by misnaming Algol-like languages Pascal-like languages.
Niklaus Wirth had better marketing. :-)
Atlant 13:08, 24 August 2005 (UTC)

Scoping

Arg. An article about LISP which fails to mention dynamic scoping. Remember that any variable in LISP can be lambda-bound inside any function and that rescoping applies to any called function? (As opposed to the more familiar lexically-scoped languages derived from Algol, C, etc.)

LISP was one of my first programming languages (I used Maclisp in college and InterLISP at work back in the 1970s), but due to my extreme age, the details of dynamic scoping have faded. Does anyone remember enough to add this important language feature to the article? - Rlw (Talk) 00:26, May 30, 2005 (UTC)

Dynamic scoping is certainly historically important, particularly in the case of early systems where interpreted functions were dynamically scoped while compiled ones were lexically scoped.


Sidebar about control structures

I'm curious about this change you made --
Lisp has very few control structures, compared to more modern procedural languages.
Common Lisp (the dialect with which I have the most experience) seems to me to have a remarkably large number of control structures. There are iteration constructs do, do*, dolist, dotimes, do-symbols, the monstrosity that is loop; the whole plethora of mapping functions; conditionals such as if, when, unless, cond, case, ecase, typecase, etypecase; four different kinds of non-local transfers of control (tagbody/go, block/return-from, catch/throw, and conditions); and so forth.
In contrast, C has just if, switch, while, for, do/while, break, continue, goto, return. Python has if, while, for, try/except/raise, break, continue, return, yield.
I'm not sure, then, what you mean by Lisp having very few control structures. This might be true of Scheme (which, like Python, is deliberately minimalist), but I don't think it's true of Lisp in general. --FOo 03:12, 30 May 2005 (UTC)
You're right. We're both right. It's a dialect issue. Originally, Lisp had little more than cond, prog, and the varieties of map such as mapcar. The other special forms you mention came later. Maclisp, for example, had catch/throw by 1974 or so, but none of the other conditionals and iteratives you mentioned. There was a certain minimalist mindset, I think, in Maclisp (as opposed to Interlisp, which we referred to at the time as the world's largest AI program), that it was more elegant to keep the number of control structures small. [In little old man voice] In the old days, we had only two control structures, and we liked it! I made a correction, see whether you find it adequate. - Rlw (Talk) 04:23, May 30, 2005 (UTC)
Spiffy.
Hmm. This Maclisp manual suggests that the compiler recognized go and return forms. This one suggests also do, error/errset, and the conditional (short-circuiting) and and or. But both of these documents are later than the 1974 date you specify.
When I started using Maclisp in 1971, it had (as RLW mentions) cond, prog (within which—and only within which—labels, go, and return were defined), and a small number of variants of map. But it also had short-circuit and and or; the single-variable form of do (e.g. (do i 0 (plus i 1) (equal i 10) (print i))); and errset for catching errors—I don't remember if error was defined for explicitly signalling an error. A recent (and elaborate) addition in 1971 was the error-handling system (concept borrowed from Interlisp) which allowed user code to handle undefined-function, division-by-zero, etc. and continue processing (in standard programming language terminology, resumptive exception handling). Individual users build things like case on top of this base using macros, and some of them later became part of the standard language. --Macrakis 14:49, 2 Jun 2005 (UTC)
By the way, I don't think this issue is unique to Lisp -- there are a lot of Wikipedia articles about computer systems and programs where there's a tension between discussing the history of foo and discussing foo as it is today. When something's history has been very influential (possibly more so than the most recent versions), it's hard to decide how to cover it. --FOo 14:03, 2 Jun 2005 (UTC)
Agreed. Having divested myself of my Lisp books (within the past 5 years, never thinking I'd look at them again, sob), I will defer to existing authoritative printed matter. Maybe it would be best to add citations to the article body to stave off these kinds of (relatively minor) version difference issues. - Rlw (Talk) 14:54, Jun 2, 2005 (UTC)

And now back to scoping. It would be great if someone with handy access to the literature could add something about Lisp scoping. And binding, too! Remember how Interlisp had allowed the programmer to specify deep or shallow binding? It took me a while to get my brain around that concept... - Rlw (Talk) 14:54, Jun 2, 2005 (UTC)

GNU Lisp

There are two links to GNU Lisps. What is the difference between the two implemenations?

This question would be better on one of their mailing lists, or comp.lang.lisp, but I'll give you a quick overview. They're entirely different implementations. If memory serves (not always a guarantee), GCL was the first Common Lisp implementation that was part of the GNU project, and CLISP was originally an independant project. GCL stagnated for a while, and wasn't brought up to the ANSI standard (which was written after GCL was started), and CLISP was made part of GNU. Now GCL development is active again.
Internally, they're very different. For example, while GCL dispatches through the C compiler to compile to native code, while CLISP uses an internal byte-code compiler. CLISP seems to be one of the more popular free Lisp implementations, from watching comp.lang.lisp, while GCL is less often seen. --Piquan 00:12, 1 Jun 2005 (UTC)

GOAL - Lisp for games

Does something like GOAL (Game Oriented Assembly Lisp - [google]) created by [Naughty Dog] game developers deserve mention somewhere?

found another mention of this and how it was killed after Sony bought naughtydog

http://lists.midnightryder.com/pipermail/sweng-gamedev-midnightryder.com/2005-August/003789.html via reddit (http://reddit.com/info?id=14ch)

Shared structure

I just want a clarification. In the section of the article about shared structure, it gives these statements:

(setq foo (list 'a 'b 'c))
(setq bar (cons 'x (cdr foo)))

with an assertion that the lists 'foo' and 'bar' now share the same tail. This occurs in Common Lisp, but not in Scheme, correct? -- 20:35, 13 September 2005 (UTC)

Well, Scheme doesn't have setq, but it does have set!, which does the same thing. Scheme systems are a little less forgiving about using set! on undefined variables, so you'll have to define foo and bar or wrap the whole thing in a let that makes them lexically available. But yes, it does the same thing. (set! bar (cons 'x (cdr foo))) causes bar and foo to share a tail. --FOo 22:45, 13 September 2005 (UTC)
Strange, I get the following when I try it in MzScheme...
> [define foo [list 'a 'b 'c]]
> [define bar []] ;just to create bar
> [set! bar [cons 'x [cdr foo]]]
> foo
(a b c)
> bar
(x b c)
> [set! foo [list 1 2 3]]
> bar
(x b c)
> foo
(1 2 3)
> 
That's because your second set! is rebinding the foo variable, rather than altering the list structure. Try (set-cdr! (cdr foo) (list 'goose)) instead, and see what that does.
Rebinding foo (by doing set! on it) does not change bar. But altering the list structure foo points to, or rather, the common tail of that structure and bar's structure, does change bar. --FOo 01:59, 14 September 2005 (UTC)
I'm still getting similar results... I changed the language to Standard R5RS. (I'm using PLT Scheme.)
> (define foo '(1 2 3))
> (define bar (cons 0 (cdr foo)))
> (set-cdr! foo '(3 5))
> foo
(1 3 5)
> bar
(0 2 3)
Are you sure Scheme doesn't prevent this sort of list modification? I.e., when executing (define bar (cons 0 (cdr foo))), first it evaluates (cdr foo) to (2 3) and then sets bar to (cons 0 (2 3))... it sure seems as if that's what's going on. It's a little strange because I don't remember seeing this distinction anywhere before. -- 02:25, 14 September 2005 (UTC)
You've changed the cdr of bar, which had been the point where it linked into foo's structure. However, you didn't change anything within the shared structure. Try this:
> (define foo '(1 2 3))
> (define bar (cons 0 (cdr foo)))
> (set-cdr! (cdr bar) '(69 105))
> foo
(1 2 69 105)
However, this may be more clear, since it doesn't rely on the extra (cdr) level of indirection:
> (define foo '(1 2 3))
> (define bar foo)
> (set-cdr! bar '(69 105))
> foo
(1 69 105)
You may want to ask in comp.lang.lisp, etc about shared structure. Piquan 03:09, 14 September 2005 (UTC)

Anonymous Contributor said: ... when executing (define bar (cons 0 (cdr foo))), first it evaluates (cdr foo) to (2 3) and then sets bar to (cons 0 (2 3))... it sure seems as if that's what's going on.

But that isn't what's going on. (cdr foo) doesn't evaluate just to any list (2 3). It evaluates to a specific list (2 3), namely the one that is part of the list pointed to by foo. It's a different (2 3) than if we conjured up a new one by saying '(2 3) or (list '2 '3).

List structures have identity, like objects in OO. (cdr foo) doesn't mean "make a new list that has the same value as the cdr of foo does." It means "return the list that is the cdr of foo."

There can be many lists that happen to have the value (2 3). But only one of them is the cdr of foo. (cdr foo) returns that specific list. (cons 'x (cdr foo)) creates a new list that shares structure with foo. And altering (cdr foo) alters foo. --FOo 03:23, 14 September 2005 (UTC)

Alright, I understand now... Thanks for the clarification! I think my confusion stemmed from the different versions of set, namely set! and set-cdr! - because set! only accepts identifiers as its first argument but set-cdr! can take something like (cdr foo) and set it to a part of another list. Ah, Lisp. -- 03:32, 14 September 2005 (UTC)
Just for a further clarification, in case there remains confusion out there, here is a bit of C code:
struct cons { int car; struct cons *cdr; };
struct cons *foo, *bar;
struct cons *NIL = NULL;
foo = make_list(1, 2, 3, NIL); /* Allocates and returns (1 . (2 . (3 . NIL))) = (1 2 3) */
bar = make_cons(0, foo->cdr); /* Allocates and returns {0, foo->cdr} = (0 . (cdr foo)) = (0 2 3) */
foo->cdr->cdr = make_list(4, 5, NIL); /* Allocates and returns (4 . (5 . NIL)) = (4 5) */
/* Note that bar == {0, foo->cdr} and foo->cdr == {2, {4, {5, NIL}}}, so bar = (0 2 4 5) */
Lisp equivalent:
(setq foo '(1 2 3))
(setq bar (cons 0 (cdr foo)))
(setf (cddr foo) '(4 5))
bar => (0 2 4 5)
Ari 22:40, 1 January 2006 (UTC)

defmacro

Also, how can defmacro be constructed from these (car, cdr, cons, quote, eq, if/cond, defun/define+lambda) basic elements? -- 22:33, 13 September 2005 (UTC)

By defining a way of creating macro-bindings (such as storing them in an alist) and a new eval function which applies them. --FOo 22:45, 13 September 2005 (UTC)
(defun defmacro (binds-as-a-list fun-as-data) ...apply-binds-to-fun-data...) something remotely like that hideous pseudo-Lisp?
Sure. When you define a macro, in one sense what you're doing is defining a macro function that accepts a piece of Lisp code (the macro call) as input, and returns a piece of Lisp code (the expanded code) as output.
When the eval function sees a form, it looks at the car of the form and asks, Is this a special operator (like define)? Is it the name of a macro? Is it a function? Consider this rudimentary eval:
(define eval (form)
   (cond
       ((is-special-operator? (car form))
        (apply-operator (car form) (cdr form)))
       ((is-macro-name? (car form))
        (eval ((get-macro-function (car form)) form)))
       ((is-function? (car form))
        ((car form) (map eval (cdr form))))
In other words, defmacro stashes a macro-function away somewhere, and when you eval a form whose car is the name of the macro, eval will call the macro-function to expand the form, then eval the rest.
(There's probably more than one bug in that eval. I don't usually use Scheme; and I don't usually write Lisp implementations either. :) Queinnec's book has macro systems in it too, I think ... if not, consult the source code to your favorite Lisp or Scheme implementation, since most are written in Lisp or Scheme.) --FOo 01:59, 14 September 2005 (UTC)
Very helpful, thank you! I don't mind bugs, just fishing for concepts here. (: -- 02:25, 14 September 2005 (UTC)

Also the eval function... sorry for all the questions, especially if it already exists somewhere obvious (or not), I'm just very curious. -- 22:41, 13 September 2005 (UTC)

You might want to look up McCarthy's original LISP [sic!] papers, in which eval is defined in terms of simpler primitives. For a more modern approach to recursively defining Lisp systems, see Christian Queinnec's Lisp In Small Pieces. --FOo 22:45, 13 September 2005 (UTC)
I just saw that book today. I'll have to go back and get it. Thanks! -- 00:55, 14 September 2005 (UTC)

BTW you can't implement defmacro as a function, because it would evaluate its arguments which is not what happens. defmacro should actually be a macro itself, based on some other function for creating macros.  Grue  06:04, 14 September 2005 (UTC)

Quotes

Should we move the "Quotes" section to Wikiquotes? Or leave it on the main article page?

Singingwolfboy 22:35, 29 September 2005 (UTC)

Contributions of 24.128.49.163

24.128.49.163 (talk · contribs) made some rather negative edits on this article. Coincidentally he made similar edits on Scheme programming language. See his edit of 20:34, 2 October 2005 and my response on the talk page. He seems to have some kind of bee in his bonnet about the lisp family, particular those dratted parentheses. :) --Tony SidawayTalk 21:28, 2 October 2005 (UTC)

Association lists

It would be nice if somebody could add some remarks about association lists and refer to Association_list#Lisp. Some notes how to use arrays and hash tables would be nice as well. Hirzel 12:44, 17 October 2005 (UTC)

Quote section

This isn't Wikiquote and it's really not necessary, nor appropriate to insert a list of "look at how great lisp is!" quotes Nathan J. Yoder 05:43, 19 October 2005 (UTC)

The quotes are relatively famous and I do not mind having them here. However it would be nice to have an additional one which might shed some light on the fact that Lisp is not widely used today. Hirzel 07:01, 19 October 2005 (UTC)
Whether or not they're famous has nothing to do with whether or not they should be included in the article. They don't actually contribute anything of value to the article and only add POV. Wikiquote was created for the purpose of listing quotes related to things, so that lists like this wouldn't be on Wikipedia. An additional quote would just make things worse. All you need to do is say "lisp is not widely used today", no need to quote someone to say something so simple, but you might want to cite some statistics (if available).
Also, I noticed someone raised this objection earlier, I didn't notice their section when I created this one. --Nathan J. Yoder 07:32, 19 October 2005 (UTC)
I disagree. I am interested to know what people think about an issue. So quotes add to the article. Currently there are only citations which are in favor of Lisp and just for this reason I suggested to include additional quotes which have a different POV. Hirzel 11:15, 20 October 2005 (UTC)
I agree with Hirzel. Including quotations each of which has a POV does not make the article POV. In fact, reporting multiple POVs is what makes it NPOV. --Macrakis 13:45, 20 October 2005 (UTC)
Including multiple "lisp is great!" POVs makes the article NPOV? How does that work? Even if there were negative quotes, that still wouldn't be NPOV (read WP:NPOV), since NPOV doesn't simply mean sticking together different views indiscriminately. What value do these quotes actually add to the article (simple fame does not add value)? Nathan J. Yoder 14:31, 20 October 2005 (UTC)
Re: use. Wasn't there a study of the Debian repositories, that if you collapse C and C++ into one language, Lisp is the third-most used language? --Maru (talk) 00:19, 20 October 2005 (UTC)
Yes, but it's misleading. Lisp comes 4th after shell scripting (C and C++ separate). They're measuring in terms of lines of code though, not in terms of number of projects. Now, there's an obvious skew from the fact that this is only OSS projects to start and there may be others based on debian packages that I'm not aware of. If you look at the results it's strange: Fortran beats PHP, with Pascal coming right after PHP. C# is really low and Visual Basic and Cobol (which actually does have a lot of actual code in use) don't even come on the radar. I'm wondering what all those lisp projects are if they're managing to beat even Perl and Java.
Here's the run down from that study: C (57), C++ (16.8), Shell (9), Lisp (3), Perl (2.8), Python (1.8), Java (1.6), Fortran (1.2), PHP (0.93), Passcal (0.62), Ada (0.61), Objective C (0.37), ML (0.31), Yacc(0.29), Ruby (0.26), C# (0.23), Lex (0.10). [3] (PDF - Measuring Libre Software Using Debian 3.1 as A Case Study: Preliminary Results).
There are several other rating methods that get different results: [4], [5], [6], and [7]. --Nathan J. Yoder 01:39, 20 October 2005 (UTC)
I was just trying to point out that it's not quite dead yet. --Maru (talk) 03:30, 20 October 2005 (UTC)

ML is impure

In the article, ML is listed as an example of a pure functional language. This is incorrect, according to what I know of ML as well as the ML page. However, I don't feel quite familiar enough with the context in this article to try and fix it myself. Can someone who knows what they are doing please fix it? SpectrumDT 19:16, 13 November 2005 (UTC)

Virtual machine implementation

I'm currently working on my own Lisp interpretter (a bit unusual though - multithreaded). I've been reading the CLISP implementation notes, and CLISP seems to have two stacks, STACK and SP. Can anyone explain why are there two stacks? What is the difference between them? Is it enough to have a stack of call frames in each thread, so that every call frame has it's own local stack? - Phraine

This would much better be asked on comp.lang.lisp. But look at what gets put on each stack - is one a Lisp-pointer-only stack and the other a C-language control stack, or ... ? Ari 02:12, 26 December 2005 (UTC)