Lisp was invented and developed by US AI labs in the 's in order to rapidly prototype symbolic logic programs in which the native Lisp data structures fit the level of symbolic abstraction required - e. English words could be symbols in a list, logic formulas could be easily represented as lists of operators and operands. But for production programs, the software engineering advantages of static typed languages and a wide variety of third-party libraries, means that Lisp is not even considered for large modern systems that perform AI tasks.
Stephen Reed said it very well. I heard a story then about the origin of Lisp. I can't swear it's true, but it goes like this:. John McCarthy was at MIT in the 50s, and he had been working on proving properties of programs, and for this he had been using a simple syntax similar to Lambda Calculus.
The story was that one of the grad students wanted to do a project analogy, or theorem proving, or symbolic math, I don't remember which and asked McCarthy what language to use. The answer - Fortran of course. There wasn't much else, and list processing itself was fairly well known then, but only as subroutine packages, not as languages.
Well, somehow that led to a program that would process symbols in nested list structures. Together with a way to read and print them, and then an eval function, and Voila' - a language. A LISt Processing language. It took off from there. For the kind of algorithms we were doing in those days and that still very few people are doing a language was needed that could easily manipulate symbolic expressions. That's what Lisp was good at. There have been many variations on the basic concept, going by different names, like Prolog, Scheme, etc.
So AI means lots of things to lots of people, and different languages are good for different things, but for problems that could be described as symbol manipulation, it's hard to find a useful language that isn't somehow descended from Lisp. Lisp has advantages for the kinds of things that were called AI - at least the logic, search and parsing related things that were most of AI up until around the 90s.
A major advantage of the ML family and Haskell, etc is pattern matching. This is probably available in Lisp too, but via a metaprogramming library rather than built into the language. It's also available in Haskell, but for the moment at least, pattern matching isn't common outside of functional programming languages. I've seen claims that LISP is basically an extended untyped lambda calculus, and ML is basically an extended typed lambda calculus. I don't have the knowledge of typed lambda calculus to say for sure.
AI has also become a much more broad subject over the years - to the point that it has almost vanished completely. Data mining could be considered one subfield of AI. Python, but rather more a question of which style of syntax is better-known. Well from what he writes, he seems to say Python looks much closer to their actual pseudo-code, and it's therefore easier for students to translate pseudocode to Python than to Lisp. One of the original goals of Python inherited from ABC[0] was to be a good teaching language.
I'd expect that when Peter talks about his students, he's mostly talking about students with low-to-no knowledge in programming. Those who are already knowledgeable probably don't have a hard time adapting. AndyKelley on Oct 19, root parent next [—]. When I took an AI class at my university with AI: A Modern Approach the book was good, if a little difficult to understand at times , we had a couple projects that we had to write in lisp.
Extra Credit 25 points Create and implement a heuristic equal to or better than MST Second project: In this project we implement a decision tree induction algorithm in Lisp. I had played around with lisp before this point and found it fascinating. I approached these projects with excitement. But even with 8 years of serious programming experience, I could not for the life of me solve these problems in lisp.
My problems included: 1. Knowing exactly what methods I wanted to call and use and either a. Not being able to find them in any reference I found online, or b.
Finding out that they don't exist, and you have to write them yourself, or c. Finding them and shaking my head at how ridiculously they were named. Not being able to read the code I had just written. Not being able to debug. Finding that manipulating common data structures like hash tables is a total chore. Eventually I gave up. I had spent about two hours trying to implement the project I had already solved in my head into common lisp and was making little or no progress.
So I fired up another vim terminal, solved the project in Python in about 30 minutes, including debugging, and then manually translated the code into lisp. When project 2 rolled around, I decided to give it another go, but I quickly became frustrated again.
Maybe my mind just isn't able to grok lisp? Maybe I'm just not smart enough? All I'm claiming is that I am an example of a student who was already very knowledgeable about programming and completely unable to adapt to lisp. Do you also find your pseudocode and therefore python clearer, or was it entirely pedagogical? Redesigning a data format to match how I notate and think about it, to minimize my cognitive load, has been very helpful to me.
The long-term trend in computers seems to be to trade performance for helping the developer. Some say that you can test hypotheses etc alone without publishing and you are doing science; but others define science as a community activity, and so without publishing, it is not 'science'. While I love the idea of the lone researcher, and clever insights definitely come from individuals, without a community there is no SOTSOG.
This is why I love HN. Robert M. Lefkowitz's PyCon Keynote discusses the "main goal is communication, not programming" in great detail.
Lisp is the most natural language in which to write complex 'symbolic reasoning' programs, which are the heart of BioBike's novel capabilities. Symbolic reasoning involves manipulating conceptual objects, such as 'genes', 'ontologies', 'pathway models', and the like, and Lisp was built specifically for this sort of manipulation although not specifically for biology at the time.
This is why it has remained popular in the most advanced computing circles, esp. As for being impossibly complex, it's not any more complex than any other programming language. Those who don't know Chinese think it's hard too, but the Chinese don't!
Many other 'modern' programming languages have been based directly on Lisp; Python, for example, is just a near approximation to Lisp. See Peter Norvig's comparison here.
You think you know when you learn, are more sure when you can write, even more when you can teach, but certain when you can program. This chapter is for people with little or no experience in Lisp. Readers who feel confident in their Lisp programming ability can quickly skim the chapter or skip it entirely.
This chapter necessarily moves quickly, so those with little programming experience, or any reader who finds this chapter tough going, should seek out a supplementary introductory text. My recommendations are in the preface. Computers allow one to carry out computations. A word processing program deals with words while a calculator deals with numbers, but the principles are the same. In both cases, you provide the input words or numbers and specify the operations such as deleting a word or adding two numbers to yield a result a completed document or calculation.
We will refer to anything that can be represented in the memory of a computer as a computational object, or just an object. So, words, paragraphs, and numbers can be objects. And because the operations deleting and adding must be represented somewhere in the computer's memory, they are objects, too.
Normally, the distinction between a computer "user" and a computer "programmer" is that the user provides new input, or data words or numbers , while the programmer defines new operations , or programs, as well as new types of data. Every new object, be it datum or operation, must be defined in terms of previously defined objects.
The bad news is that it can be quite tedious to get these definitions right. The good news is that each new object can in turn be used in the definition of future objects.
Thus, even complex programs can be built out of smaller, simpler objects. This book covers a number of typical AI problems, showing how each problem can be broken down into manageable pieces, and also how each piece can be described in the programming language Common Lisp. Ideally, readers will learn enough through studying these examples to attack new AI problems with style, grace, and success. Let's consider a simple example of a computation: finding the sum of two numbers, let's say 2 and 2.
In Lisp, as with the calculator, the user carries out an interactive dialog with the computer by typing in an expression and seeing the computer print the value of that expression. This interactive mode is different from many other programming languages that only offer a batch mode, wherein an entire program is compiled and run before any output can be seen.
The Lisp program must also be started, but the details vary from one computer to another, so I can't explain how your Lisp will work.
Assuming we have managed to start up Lisp, we are likely to see a prompt of some kind. So we are faced with a screen that looks like this:. We may now type in our computation and see the result displayed. It turns out that the Lisp convention for arithmetic expressions is slightly different: a computation consists of a parenthesized list with the operation name first, followed by any number of operands, or arguments. This is called prefix notation.
Throughout this book, all Lisp expressions will be displayed in typewriter font. One advantage of parenthesized prefix notation is that the parentheses clearly mark the beginning and end of an expression. This example shows that expressions can be nested. In Lisp, lists are evaluated by first evaluating all the arguments, then applying the function to the arguments, thereby computing the result. This rule is much simpler than the rule for evaluating normal mathematical expressions, where there are many conventions to remember, such as doing multiplications and divisions before sums and differences.
We will see below that the actual Lisp evaluation rule is a little more complicated, but not much. Sometimes programmers who are familiar with other languages have preconceptions that make it difficult for them to learn Lisp.
For them, three points are worth stressing here. First, many other languages make a distinction between statements and expressions. Statements have effects, but they do not return values. In Lisp, there is no such distinction: every expression returns a value. It is true that some expressions have effects, but even those expressions also return values.
Second, the lexical rules for Lisp are much simpler than the rules for other languages. In particular, there are fewer punctuation characters: only parentheses, quote marks single, double, and backward , spaces, and the comma serve to separate symbols from each other.
Third, while many languages use semicolons to delimit statements, Lisp has no need of semicolons, since expressions are delimited by parentheses.
Lisp chooses to use semicolons for another purpose—to mark the beginning of a comment, which lasts until the end of the line:. All we've done so far is manipulate numbers in the same way a simple pocket calculator would. Lisp is more useful than a calculator for two main reasons. First, it allows us to manipulate objects other than numbers, and second, it allows us to define new objects that might be useful in subsequent computations. We will examine these two important properties in turn.
Besides numbers, Lisp can represent characters letters , strings of characters, and arbitrary symbols, where we are free to interpret these symbols as referring to things outside the world of mathematics.
Lisp can also build nonatomic objects by combining several objects into a list. This capability is fundamental and well supported in the language; in fact, the name Lisp is short for LISt Processing. This expression appends together two lists of names. The rule for evaluating this expression is the same as the rule for numeric calculations: apply the function in this case append to the value of the arguments. The unusual part is the quote mark ' , which serves to block the evaluation of the following expression, returning it literally.
If we just had the expression Pat Kim , it would be evaluated by considering Pat as a function and applying it to the value of the expression Kim. This is not what we had in mind. The quote mark instructs Lisp to treat the list as a piece of data rather than as a function call:.
In other computer languages and in English , quotes usually come in pairs: one to mark the beginning, and one to mark the end. In Lisp, a single quote is used to mark the beginning of an expression.
Since we always know how long a single expression is—either to the end of an atom or to the matching parenthesis of a list—we don't need an explicit punctuation mark to tell us where the expression ends. Quotes can be used on lists, as in ' Pat Kim , on symbols as in 'Robin , and in fact on anything else. Here are some examples:. Note that '2 evaluates to 2 because it is a quoted expression, and 2 evaluates to 2 because numbers evaluate to themselves.
Same result, different reason. In contrast, ' John evaluates to John because it is a quoted expression, but evaluating John leads to an error, because evaluating a symbol means getting the value of the symbol, and no value has been assigned to John.
Symbolic computations can be nested and even mixed with numeric computations. The following expression builds a list of names in a slightly different way than we saw before, using the built-in function list. We then see how to find the number of elements in the list, using the built-in function length:.
First, it is important to remember that Lisp does not attach any external significance to the objects it manipulates.
For example, we naturally think of Robin Sandy as a list of two first names, and John Q Public as a list of one person's first name, middle initial, and last name.
Lisp has no such preconceptions. To Lisp, both Robin and xyzzy are perfectly good symbols. Learning a language involves remembering vocabulary items or knowing where to look them up as well as learning the basic rules for forming expressions and determining what they mean. Common Lisp provides over built-in functions. At some point the reader should flip through a reference text to see what's there, but most of the important functions are presented in part I of this book.
Third, note that symbols in Common Lisp are not case sensitive. Some programmers are more liberal in naming variables, and include characters like '?! There are a few exceptions to these naming conventions, which will be dealt with as they come up. We have seen some of the basics of symbolic computation. Now we move on to perhaps the most important characteristic of a programming language: the ability to define new objects in terms of others, and to name these objects for future use.
Here symbols again play an important role-they are used to name variables. A variable can take on a value, which can be any Lisp object. One way to give a value to a variable is with setf :. After assigning the value John Q Public to the variable named p , we can refer to the value with the name p. Similarly, after assigning a value to the variable named x , we can refer to both x and p. Symbols are also used to name functions in Common Lisp.
Every symbol can be used as the name of a variable or a function, or both, although it is rare and potentially confusing to have symbols name both. For example, append and length are symbols that name functions but have no values as variables, and pi does not name a function but is a variable whose value is 3. The careful reader will note that setf violates the evaluation rule. But setf doesn't follow that rule, because setf is not a function at all.
Rather, it is part of the basic syntax of Lisp. Besides the syntax of atoms and function calls, Lisp has a small number of syntactic expressions. They are known as special forms. They serve the same purpose as statements in other programming languages, and indeed have some of the same syntactic markers, such as if and loop. There are two main differences between Lisp's syntax and other languages. First, Lisp's syntactic forms are always lists in which the first element is one of a small number of privileged symbols.
Second, special forms are expressions that return a value. This is in contrast to statements in most languages, which have an effect but do not return a value.
In evaluating an to expression ed note:??? The philosophy of Lisp is to provide a small number of special forms to do the things that could not otherwise be done, and then to expect the user to write everything else as functions. The term special form is used confusingly to refer both to symbols like setf and expressions that start with them, like setf x 3.
In the book Common LISPcraft, Wilensky resolves the ambiguity by calling setf a special function, and reserving the term special form for setf x 3. This terminology implies that setf is just another function, but a special one in that its first argument is not evaluated. Such a view made sense in the days when Lisp was primarily an interpreted language.
The modern view is that setf should not be considered some kind of abnormal function but rather a marker of special syntax that will be handled specially by the compiler. When there is risk of confusion, we will call setf a special form operator and setf x 3 a special form expression. It turns out that the quote mark is just an abbreviation for another special form. The special form operators used in this chapter are:.
0コメント