Path: think.com!zaphod.mps.ohio-state.edu!uwm.edu!ogicse!das-news.harvard.edu!cantaloupe.srv.cs.cmu.edu!crabapple.srv.cs.cmu.edu!mkant From: mkant+@cs.cmu.edu (Mark Kantrowitz) Newsgroups: comp.lang.lisp,news.answers Subject: FAQ: Lisp Frequently Asked Questions 1/5 [Monthly posting] Summary: Introductory Matter and Bibliography of Introductions and References Message-ID: Date: 14 Aug 92 00:37:11 GMT Article-I.D.: cs.lisp-faq-1.text_713752615 Expires: Sun, 27 Sep 1992 00:36:55 GMT Sender: news@cs.cmu.edu (Usenet News System) Reply-To: lisp-faq@think.com Followup-To: poster Organization: School of Computer Science, Carnegie Mellon Lines: 769 Approved: news-answers-request@MIT.Edu Supersedes: Nntp-Posting-Host: a.gp.cs.cmu.edu Xref: think.com comp.lang.lisp:8023 news.answers:2525 Archive-name: lisp-faq/part1 Last-Modified: Thu Aug 6 11:54:55 1992 by Mark Kantrowitz Version: 1.23 ;;; **************************************************************** ;;; Answers to Frequently Asked Questions about Lisp *************** ;;; **************************************************************** ;;; Written by Mark Kantrowitz and Barry Margolin ;;; lisp-faq-1.text -- 34247 bytes This post contains Part 1 of the Lisp FAQ. If you think of questions that are appropriate for this FAQ, or would like to improve an answer, please send email to us at lisp-faq@think.com. Note that the lisp-faq mailing list is for discussion of the content of the FAQ posting. It is not the place to ask questions about Lisp; use either the common-lisp@ai.sri.com mailing list or the comp.lang.lisp newsgroup for that. If a question appears frequently in one of those forums, it will get added to the FAQ list. There are currently five parts to the Lisp FAQ: 1. Introductory Matter and Bibliography of Introductions and References 2. General Questions 3. Common Pitfalls 4. Lisp/Scheme Implementations and Mailing Lists 5. CLOS and PCL Questions Part 4 is cross-posted to the comp.lang.scheme newsgroup. Part 5 is cross-posted to the comp.lang.clos newsgroup. Topics Covered (Part 1): [1-0] What is the purpose of this newsgroup? [1-1] What documentation is available on Lisp? How can I learn Lisp? [1-2] How can I improve my Lisp programming style and coding efficiency? [1-3] Where can I learn about implementing Lisp interpreters and compilers? [1-4] What does CLOS, PCL, X3J13, CAR, CDR, ... mean? Topics Covered (Part 2): [2-0] What FTP resources are available? [2-1] Is there a GNU-Emacs interface to Lisp? [2-2] How can I use the X Window System or other GUIs from Lisp? [2-3] When is it right to use EVAL? [2-4] What is the equivalent of EXPLODE and IMPLODE in Common Lisp? [2-5] Is Lisp inherently slower than more conventional languages such as C? [2-6] Why does my program's behavior change each time I use it? [2-7] Why does Common Lisp have "#'"? [2-8] How do I call non-Lisp functions from Lisp? [2-9] Can I call Lisp functions from other languages? [2-10] I want to call a function in a package that might not exist at compile time. How do I do this? [2-11] What is CDR-coding? [2-12] What is garbage collection? [2-13] How do I save an executable image of my loaded Lisp system? How do I run a Unix command in my Lisp? How do I get the current directory name from within a Lisp program? [2-14] I'm porting some code from a Symbolics Lisp machine to some other platform, and there are strange characters in the code. What do they mean? [2-15] History: Where did Lisp come from? [2-16] How do I find the argument list of a function? [2-17] How can I have two Lisp processes communicate via unix sockets? [2-18] When producing formatted output in Lisp, where should you put the newlines (e.g., before or after the line, FRESH-LINE vs TERPRI, ~& vs ~% in FORMAT)? Common Pitfalls (Part 3): [3-0] Why does (READ-FROM-STRING "foobar" :START 3) return FOOBAR instead of BAR? [3-1] Why can't it deduce from (READ-FROM-STRING "foobar" :START 3) that the intent is to specify the START keyword parameter rather than the EOF-ERROR-P and EOF-VALUE optional parameters? [3-2] Why can't I apply #'AND and #'OR? [3-3] I used a destructive function (e.g. DELETE, SORT), but it didn't seem to work. Why? [3-4] After I NREVERSE a list, it's only one element long. After I SORT a list, it's missing things. What happened? [3-5] Why does (READ-LINE) return "" immediately instead of waiting for me to type a line? [3-6] I typed a form to the read-eval-print loop, but nothing happened. Why? [3-7] DEFMACRO doesn't seem to work. When I compile my file, LISP warns me that my macros are undefined functions, or complains "Attempt to call which is defined as a macro. [3-8] Name conflict errors are driving me crazy! (EXPORT, packages) [3-9] Closures don't seem to work properly when referring to the iteration variable in DOLIST, DOTIMES and DO. [3-10] What is the difference between FUNCALL and APPLY? [3-11] Miscellaneous things to consider when debugging code. Lisp/Scheme Implementations and Mailing Lists (Part 4): [4-0] Where can I get/buy Lisp and Scheme for the ... architecture? [4-1] Where can I get an implementation of Prolog in Lisp? [4-2] What is Dylan? [4-3] What Lisp-related discussion groups and mailing lists exist? CLOS Questions (Part 5): [5-0] What is CLOS (PCL) and where can I get it? How do you pronounce CLOS? [5-1] What documentation is available about object-oriented programming in Lisp? [5-2] How I write a function that can access defstruct slots by name? I would like to write something like (STRUCTURE-SLOT '). [5-3] How can I list all the CLOS instances in a class? [5-4] How can I store data and CLOS instances (with possibly circular references) on disk so that they may be retrieved at some later time? [5-5] Given the name of a class, how can I get the names of its slots? Search for [#] to get to question number # quickly. Introduction: Certain questions and topics come up frequently in the various network discussion groups devoted to and related to Lisp. This file/article is an attempt to gather these questions and their answers into a convenient reference for Lisp programmers. It (or a reference to it) is posted periodically. The hope is that this will cut down on the user time and network bandwidth used to post, read and respond to the same questions over and over, as well as providing education by answering questions some readers may not even have thought to ask. This is not a Lisp tutorial, nor is it an exhaustive list of all Lisp intricacies. Lisp is a very powerful and expressive language, but with that power comes many complexities. This list attempts to address the ones that average Lisp programmers are likely to encounter. If you are new to Lisp, see the answer to the question "How can I learn Lisp?". The latest version of this file is available via anonymous FTP from CMU and Thinking Machines: To obtain the files from CMU, connect by anonymous ftp to any CMU CS machine (e.g., ftp.cs.cmu.edu [128.2.206.173]), using username "anonymous" and password "name@host". The files lisp-faq-1.text, lisp-faq-2.text, lisp-faq-3.text, lisp-faq-4.text and lisp-faq-5.text are located in the directory /afs/cs.cmu.edu/user/mkant/Public/Lisp-Utilities/ [Note: You must cd to this directory in one atomic operation, as some of the superior directories on the path are protected from access by anonymous ftp.] If your site runs the Andrew File System, you can just cp the files directly without bothering with FTP. To obtain the files from Thinking Machines, ftp them from ftp.think.com, in the directory /public/think/lisp/. The file faq.text contains all the parts of the FAQ in one file. In addition, specific versions of the FAQ are available as faq-.text. Unless otherwise specified, the Lisp dialect referred to is Common Lisp, as defined by "Common Lisp: the Language" (aka "CLtL") as well as corrections (but not enhancements) from "Common Lisp: the Language, 2nd Edition" (aka "CLtL2"), both by Guy L. Steele, Jr. and published by Digital Press. Enhancements such as CLOS, conditions, and the LOOP macro will be referred to separately. ---------------------------------------------------------------- [1-0] What is the purpose of this newsgroup? The newsgroup comp.lang.lisp exists for general discussion of topics related to the programming language Lisp. For example, possible topics can include (but are not necessarily limited to): announcements of Lisp books and products discussion of programs and utilities written in Lisp discussion of portability issues questions about possible bugs in Lisp implementations problems porting an implementation to some architecture Postings should be of general interest to the Lisp community. See also question [4-2]. Questions about object oriented programming in Lisp should be directed to the newsgroup comp.lang.clos. Similarly, questions about the programming language Scheme should be directed to the newsgroup comp.lang.scheme. Discussion of AI programs implemented in Lisp should sometimes be cross-posted to the newsgroup comp.ai. ---------------------------------------------------------------- [1-1] What documentation is available on Lisp? How can I learn Lisp? There are several good Lisp introductions and tutorials: 1. David S. Touretzky "Common Lisp: A Gentle Introduction to Symbolic Computation" Benjamin/Cummings Publishers, 1990. 384 pages. Perhaps the best tutorial introduction to the language. It has clear and correct explanations, and covers some fairly advanced topics. The book is an updated Common Lisp version of the 1984 edition published by Harper and Row Publishers. 2. Robert Wilensky "Common LISPcraft" W. W. Norton, 1986. 385 pages. 3. Wade L. Hennessey "Common Lisp" McGraw-Hill, 1989. 395 pages. Fairly good, but jumps back and forth from the simple to the complex rather quickly, with no clear progression in difficulty. 4. Laurent Siklossy "Let's Talk LISP" Prentice-Hall, NJ, 1976. 237 pages. Good introduction, but quite out of date. 5. Stuart C. Shapiro "Common Lisp: An Interactive Approach" Computer Science Press/W.H. Freeman, New York, 1992. ISBN 0-7167-8218-9 Other introductions to Lisp include: 1. A. A. Berk. "LISP, The Language of Artificial Intelligence" Van Nostrand Reinhold, 1985. 160 pages. 2. Paul Y. Gloess. "An Alfred handy guide to Understanding LISP" Alfred Publishers (Sherman Oaks, CA), 1982. 64 pages. 3. Ward D. Maurer. "The Programmer's Introduction to LISP" American Elsevier, 1972. 112 pages. 4. Hank Bromley and Richard Lamson. "LISP Lore: A Guide to Programming the LISP Machine" Kluwer Academic (Boston), 1987. 337 pages. 5. Sharam Hekmatpour. "Introduction to LISP and Symbol Manipulation" Prentice Hall (New York), 1988. 303 pages. 6. Deborah G. Tatar "A programmer's guide to Common Lisp" Digital Press, 1987. 327 pages. ISBN 0-932376-87-8. Good introduction on Common Lisp. More advanced introductions to Lisp and its use in Artificial Intelligence include: 1. Peter Norvig. "Paradigms of AI Programming: Case Studies in Common Lisp" Morgan Kaufmann, 1992. 946 pages. ISBN 1-55860-191-0. Provides an in-depth exposition of advanced AI programming techniques and includes large-scale detailed examples. The book is the most advanced AI/Common-Lisp programming text and reference currently available, and hence is not for the complete novice. It focuses on the programming techniques necessary for building large AI systems, including object-oriented programming, and has a strong performance orientation. The text is marked by its use of "non-toy" examples to illustrate the techniques. All of the examples are written in Common Lisp, and copies of the source code are available by anonymous ftp from unix.sri.com:pub/norvig and on disk in Macintosh or DOS format from the publisher. Some of the techniques described include rule-based pattern matching (GPS, Eliza, a subset of Macsyma, the Emycin expert system shell), constraint propagation and backtracking (Waltz line-labelling), alpha-beta search (Othello), natural language processing (top-down, bottom-up and chart parsing), logic-programming (unification and Prolog), interpreters and compilers for Scheme, and object-oriented programming (CLOS). The examples are also used to illustrate good programming style and efficiency. There is a guide to trouble-shooting and debugging Lisp programs, a style guide, and a discussion of portability problems. Some of the efficiency techniques described include memoization, data indexing, compilation, delaying computation, proper use of declarations, avoiding garbage collection, and choosing and using the correct data structure. The book also serves as an advanced introduction to Common Lisp, with sections on the Loop macro, CLOS and sequences, and some coverage of error handling, series, and the package facility. 2. Eugene Charniak, Christopher K. Riesbeck, Drew V. McDermott and James R. Meehan. "Artificial Intelligence Programming", 2nd edition. Lawrence Erlbaum Associates (Hillsdale, NJ), 1987. 533 pages. Provides many nice code fragments, all of which are written in Common Lisp. The first half of the book covers topics like macros, the reader, data structures, control structures, and defstructs. The second half of the book describes programming techniques specific to AI, such as discrimination nets, production systems, deductive database retrieval, logic programming, and truth maintenance. 3. Patrick H. Winston and Berthold K. P. Horn. "LISP", 3rd edition. Addison-Wesley (Reading, MA), 1989. 611 pages. ISBN 0-201-08319-1 Covers the basic concepts of the language, but also gives a lot of detail about programming AI topics such as rule-based expert systems, forward chaining, interpreting transition trees, compiling transition trees and finding patterns in images. Not a tutorial. Has many good examples. 4. Rodney A. Brooks. "Programming in Common Lisp" Wiley, 1985. 303 pages. 5. John R. Anderson, Albert T. Corbett, and Brian J. Reiser. "Essential LISP" Addison-Wesley (Reading, MA), 1987. 352 pages. Concentrates on how to use Lisp with iteration and recursion. 6. Robert D. Cameron and Anthony H. Dixon "Symbolic Computing with Lisp" Prentice-Hall, 1992, 326 pages. ISBN 0-13-877846-9. The book is intended primarily as a third-year computer science text. In terms of programming techniques, it emphasizes recursion and induction, data abstraction, grammar-based definition of Lisp data structures and functional programming style. It uses two Lisp languages: (1) a purely functional subset of Lisp called Small Lisp and (2) Common Lisp. An MS-DOS interpreter for Small Lisp (including source) is provided with the book. It considers applications of Lisp to formal symbolic data domains: algebraic expressions, logical formulas, grammars and programming languages. 7. Hasemer and Domingue. "Common Lisp Programming for Artificial Intelligence" Addison-Wesley, 1989. General Lisp reference books include: 1. Guy L. Steele "Common Lisp: The Language" [CLtL1] Digital Press, 1984. 465 pages. ISBN 0-932376-41-X. 2. Guy L. Steele "Common Lisp: The Language, 2nd Edition" [CLtL2] Digital Press, 1990. 1029 pages. ISBN 1-55558-041-6. 3. Franz Inc. "Common Lisp: The Reference" Addison-Wesley, Reading, MA 1988. ISBN 0-201-11458-5 Entries on lisp functions in alphabetical order. 4. K. Dybvig. "The Scheme programming language" Prentice Hall, 1987. Good reference for Scheme. Lisp periodicals include: 1. LISP Pointers. Published by ACM SIGPLAN six times a year. Volume 1, Number 1 was April-May 1987. 2. LISP and Symbolic Computation, Kluwer Academic Press. Volume 1 was published in 1989. (jlz@lucid.com is the editor). 3. Proceedings of the biannual ACM Lisp and Functional Programming Conference. (First one was in 1980.) 4. Proceedings of the annual Lisp Users and Vendors Conference. Introductions to Scheme (Many books on Scheme are worth reading even if you use Common Lisp, because many of the issues are similar): 1. Harold Abelson and Gerald Jay Sussman, with Julie Sussman. "Structure and Interpretation of Computer Programs" MIT Press (Cambridge, MA) and McGraw-Hill (New York), 1985. 542 pages. ISBN 0-262-01077-1 Starts off introductory, but rapidly gets into powerful Lisp-particular constructs, such as using closures and engines, building interpreters, compilers and object-oriented systems. 2. Daniel P. Friedman and M. Felleisen. "The Little LISPer" Science Research Associates (Chicago), 1974. 58 pages. MIT Press (Cambridge, MA), 1987. ISBN 0-262-56038-0. Good for a quick introduction. Uses Scheme instead of Common Lisp. (SRA edition uses a dialect of Scheme with footnotes about translating to Scheme or Common Lisp. The MIT Press edition is in Scheme without the footnotes.) 3. George Springer and Daniel P. Friedman "Scheme and the Art of Programming" MIT Press and McGraw Hill, 1989, 400 pages. MIT Press and McGraw Hill, 1990, 596 pages. Introduces basic concepts of programming in Scheme. Also deals with object oriented programming, co-routining, continuations. 4. Wolfgang Kreutzer and Bruce McKenzie "Programming for Artificial Intelligence: Methods, Tools and Applications" Addison-Wesley (Reading, MA), 1990. 682 pages. ISBN 0-201-41621-2. Discusses Scheme, Prolog, and Smalltalk, gives an overview of the history and philosophy of AI, surveys three major programming paradigms (procedural, declarative, and object-oriented), and metaphors to AI programming. 5. Smith "Introduction to Scheme" 1988. Focuses on PC Scheme. 6. Michael Eisenberg "Programming in Scheme" Scientific Press (Redwood City, CA), 1988. 304 pages. ---------------------------------------------------------------- [1-2] How can I improve my Lisp programming style and coding efficiency? There are several books about Lisp programming style, including: 1. Molly M. Miller and Eric Benson "Lisp Style and Design" Digital Press, 1990. 214 pages. ISBN 1-55558-044-0. How to write large Lisp programs and improve Lisp programming style. Uses the development of Lucid CL as an example. 2. Robin Jones, Clive Maynard, and Ian Stewart. "The Art of Lisp Programming" Springer-Verlag, 1989. 169 pages. 3. W. Richard Stark. "LISP, Lore, and Logic: an algebraic view of LISP programming, foundations, and applications" Springer-Verlag, 1990. 278 pages. ISBN 0-387-97072-X Self-modifying code, self-reproducing programs, etc. 4. CMU CL User's Manual, Chapter 7, (talks about writing efficient code). It is available by anonymous ftp from any CMU CS machine (e.g., ftp.cs.cmu.edu [128.2.206.173]) as the file /afs/cs.cmu.edu/project/clisp/docs/cmu-user/cmu-user.ps [when getting this file by anonymous ftp, one must cd to the directory in one atomic operation, as some of the superior directories on the path are protected from access by anonymous ftp.] 5. See also Norvig's book, SICP (Abelson & Sussman), SAP (Springer and Friedman). Here are some general suggestions/notes about improving Lisp programming style, readability, correctness and efficiency: Functions often abused or misunderstood by novices: - EVAL - PROGV. PROGV modifies the dynamic bindings of variables and is often misused in conjunction with EVAL, which uses the dynamic environment. In general, avoid unnecessary use of special variables. - CATCH and THROW. Often a named BLOCK and RETURN-FROM are more appropriate. - Destructive operations, such as NCONC, SORT, DELETE, RPLACA, and RPLACD, should be used carefully and sparingly. In general, trust the garbage collector: allocate new data structures when you need them. Think twice before using any of these functions. To improve the readability of your code, - Don't use any C{A,D}R functions with more than two letters between the C and the R. When nested, they become hard to read. If you have complex data structures, you are often better off describing them with a DEFSTRUCT, even if the type is LIST. If you must use C{A,D}R, try to use destructuring-bind instead, or at least SECOND, THIRD, NTH, NTHCDR, etc. - Use COND instead of IF and PROGN. In general, don't use PROGN if there is a way to write the code within an implicit progn. For example, (if (foo x) (progn (print "hi there") 23) 34) should be written using COND instead. - Never use a 2-argument IF or a 3-argument IF with second argument NIL unless you want to emphasize the return value; use WHEN and UNLESS instead. - Use backquote, rather than explicit calls to LIST, CONS, and APPEND, whenever writing a form which produces a Lisp form. - Make the names of special (global) variables start and end with an asterisk (*). Stylistic preferences: - Use (SETF (CAR ..) ..) and (SETF (CDR ..) ..) in preference to RPLACA and RPLACD. - Many programmers religiously avoid using CATCH, THROW, BLOCK, PROG, and TAGBODY. Correctness and efficiency issues: - The ARRAY-TOTAL-SIZE-LIMIT may be as small as 1024, and the CALL-ARGUMENTS-LIMIT may be as small as 50. - Avoid using APPLY to flatten lists. (apply #'append list-of-lists) is compiled into a function call, and can run into problems with the CALL-ARGUMENTS-LIMIT. Use REDUCE or MAPCAR instead: (reduce #'append list-of-lists :from-end t) (mapcan #'copy-list list-of-lists) The second will often be more efficient (see note below about choosing the right algorithm). - NTH must cdr down the list to reach the elements you are interested in. If you don't need the structural flexibility of lists, try using vectors and the ELT function instead. - Don't use quoted constants where you might later destructively modify them. For example, instead of writing '(c d) in (defun foo () (let ((var '(c d))) ..)) write (list 'c 'd) instead. Using a quote here can lead to unexpected results later. If you later destructively modify the value of var, this is self-modifying code! Some Lisp compilers will complain about this, since they like to make constants read-only. Modifying constants has undefined results in ANSI CL. See also the answer to question [2-7]. Similarly, beware of shared list structure arising from the use of backquote. Any sublist in a backquoted expression that doesn't contain any commas can share with the original source structure. - Don't proclaim unsafe optimizations, such as (proclaim '(optimize (safety 0) (speed 3) (space 1))) since this yields a global effect. Instead, add the optimizations as local declarations to small pieces of well-tested, performance-critical code: (defun well-tested-function () (declare (optimize (safety 0) (speed 3) (space 1))) ..) Such optimizations can remove run-time type-checking, which is necessary unless you've very carefully checked your code and added all the appropriate type declarations. - Don't add declarations to code until it is fully debugged. Incorrect declarations can be an annoying source of errors. Use CHECK-TYPE liberally while developing code, if you later intend to add declarations. To produce efficient code, - choose the right algorithm. For example, consider seven possible implementations of COPY-LIST: (defun copy-list (list) (let ((result nil)) (dolist (item list result) (setf result (append result (list item)))))) (defun copy-list (list) (let ((result nil)) (dolist (item list (nreverse result)) (push item result)))) (defun copy-list (list) (mapcar #'identity list)) (defun copy-list (list) (let ((result (make-list (length list)))) (do ((original list (cdr original)) (new result (cdr new))) ((null original) result) (setf (car new) (car original))))) (defun copy-list (list) (when list (let* ((result (list (car list))) (tail-ptr result)) (dolist (item (cdr list) result) (setf (cdr tail-ptr) (list item)) (setf tail-ptr (cdr tail-ptr)))))) (defun copy-list (list) (loop for item in list collect item)) (defun copy-list (list) (if (consp list) (cons (car list) (copy-list (cdr list))) list)) The first uses APPEND to tack the elements onto the end of the list. Since APPEND must traverse the entire partial list at each step, this yields a quadratic running time for the algorithm. The second implementation improves on this by iterating down the list twice; once to build up the list in reverse order, and the second time to reverse it. The efficiency of the third depends on the Lisp implementation, but it is usually similar to the second, as is the fourth. The fifth algorithm, however, iterates down the list only once. It avoids the extra work by keeping a pointer (reference) to the last cons of the list and RPLACDing onto the end of that. Use of the fifth algorithm may yield a speedup. Note that this contradicts the earlier dictum to avoid destructive functions. To make more efficient code one might selectively introduce destructive operations in critical sections of code. Nevertheless, the fifth implementation may be less efficient in Lisps with cdr-coding, since it is more expensive to RPLACD cdr-coded lists. Depending on the implementation of nreverse, however, the fifth and second implementations may be doing the same amount of work. The sixth example uses the Loop macro, which usually expands into code similar to the third. The seventh example copies dotted lists, and runs in linear time. It's equivalent to the other linear-time examples in a lisp that is properly tail-recursive. To get an implementation of copy-tree, replace (car list) with (copy-list (car list)). - use type declarations liberally in time-critical code, but only if you are a seasoned Lisp programmer. Appropriate type declarations help the compiler generate more specific and optimized code. It also lets the reader know what assumptions were made. For example, if you only use fixnum arithmetic, adding declarations can lead to a significant speedup. If you are a novice Lisp programmer, you should use type declarations sparingly, as there may be no checking to see if the declarations are correct. Wrong declarations can lead to errors in otherwise correct code, and can limit the reuse of code in other contexts. Depending on the Lisp compiler, it may also be necessary to declare the type of results using THE, since some compilers don't deduce the result type from the inputs. - check the code produced by the compiler by using the disassemble function ---------------------------------------------------------------- [1-3] Where can I learn about implementing Lisp interpreters and compilers? Books about Lisp implementation include: 1. John Allen "Anatomy of Lisp" McGraw-Hill, 1978. 446 pages. ISBN 0-07-001115-X 2. Samuel Kamin "Programming Languages, An Interpreter-Based Approach" Addison-Wesley. ISBN 0-201-06824-9 Includes sources to several interpreters for Lisp-like languages, and a pointer to sources via anonymous ftp. 3. Sharam Hekmatpour "Lisp: A Portable Implementation" Prentice Hall, 1985. ISBN 0-13-537490-X. Describes a portable implementation of a small dynamic Lisp interpreter (including C source code). 4. Peter Henderson "Functional Programming: Application and Implementation" Prentice-Hall (Englewood Cliffs, NJ), 1980. 355 pages. 5. Peter M. Kogge "The Architecture of Symbolic Computers" McGraw-Hill, 1991. ISBN 0-07-035596-7. Includes sections on memory management, the SECD and Warren Abstract Machines, and overviews of the various Lisp Machine architectures. 6. Daniel P. Friedman, Mitchell Wand, and Christopher T. Haynes "Essentials of Programming Languages" MIT Press, 1992, 536 pages. ISBN 0-262-06145-7. Teaches fundamental concepts of programming language design by using small interpreters as examples. Covers most of the features of Scheme. Includes a discussion of parameter passing techniques, object oriented languages, and techniques for transforming interpreters to allow their implementation in terms of any low-level language. Also discusses scanners, parsers, and the derivation of a compiler and virtual machine from an interpreter. 7. Also see the proceedings of the biannual ACM Lisp and Functional Programming conferences, and the implementation notes for CMU Common Lisp. ---------------------------------------------------------------- [1-4] What does CLOS, PCL, X3J13, CAR, CDR, ... mean? Glossary of acronyms: CAR Originally meant "Contents of Address portion of Register", which is what CAR actually did on the IBM 704. CDR Originally meant "Contents of Decrement portion of Register", which is what CDR actually did on the IBM 704. Pronounced "Cudder". LISP Originally from "LISt Processing" GUI Graphical User Interface CLOS Common Lisp Object System. The object oriented programming standard for Common Lisp. Based on Symbolics FLAVORS and Xerox LOOPS, among others. Pronounced either as "See-Loss" or "Closs". See also PCL. PCL Portable Common Loops. A portable CLOS implementation. Available by anonymous ftp from parcftp.xerox.com:pcl/. LOOPS Lisp Object Oriented Programming System. A predecessor to CLOS on Xerox Lisp machines. X3J13 Subcommittee of the ANSI committee X3 which is working on the ANSI Standardization of Common Lisp. ANSI American National Standards Institute CL Common Lisp SC22/WG16 The full name is ISO/IEC JTC 1/SC 22/WG 16. It stands for International Organization for Standardization/International Electronics(?) Congress(?) Joint Technical Committee 1, Subcommittee 22, Working Group 16. This long-winded name is the ISO working group working on an international Lisp standard, (i.e., the ISO analogue to X3J13). CLtL1 First edition of Guy Steele's book, "Common Lisp the Language". CLtL2 Second edition of Guy Steele's book, "Common Lisp the Language". SICP Abelson and Sussman's book "Structure and Interpretation of Computer Programs". SCOOPS An experimental object-oriented programming language for Scheme. R3RS Revised^3 Report on the Algorithmic Language Scheme. R4RS Revised^4 Report on the Algorithmic Language Scheme. ---------------------------------------------------------------- ;;; ******************************** ;;; Change Log ********************* ;;; ******************************** ;;; Date Who Ver Reason ;;; ------------------------------------------------------------ ;;; 7-FEB-92 mk 1.0 Initial release. ;;; 10-FEB-92 mk 1.1 Pre-release corrections and additions. ;;; 10-FEB-92 mk 1.11 Minor changes from Arun Welch, Mitch Marks, ;;; Mike Meyer, Matthias Felleisen, and John Gateley. ;;; 11-FEB-92 mk 1.12 Corrections by John Carroll, Jason Trenouth, Joel ;;; Riedesel, David Neves, Lawrence Mayka and ;;; Bruce Miller. ;;; 13-FEB-92 mk 1.13 Renumbering. Split into 3 files. Some more FAQs. ;;; 23-MAR-92 mk 1.14 Updated various FTP entries, bug in EXPLODE. ;;; Updated harlequin entry. ;;; 25-MAR-92 mk 1.15 Added question [2-18]: saving data and CLOS ;;; instances to disk for later retrieval. ;;; 1-MAY-92 mk 1.17 Added entry for Feel to question [1-5]. Updated CMU ;;; ftp machines to point to ftp.cs.cmu.edu. Fixed CMU ;;; CL entry to be approximately version independent. ;;; Revised entry on Garnet. uunet.uu.net -> ftp.uu.net ;;; 12-MAY-92 mk 1.18 Split questions 1-5, 1-6, and 1-7 into part 4, ;;; which is now cross-posted to comp.lang.scheme, and ;;; questions 1-8, 2-3, 2-9 and 2-18 into part 5 which ;;; is now cross-posted to comp.lang.clos. ;;; Added detail to Norvig entry in 1-1. ;;; Updated entries for several Lisp implementations. ;;; 26-MAY-92 mk 1.19 Changed 5-2 on the basis of comments by Jeff Greif. ;;; 29-MAY-92 mk 1.20 Added question [2-17] about lisp sockets. ;;; 16-JUN-92 mk 1.21 Moved the question about object oriented ;;; programming references to part 5 of the FAQ. ;;; Entry on Dylan. Addition to MIT Scheme entry ;;; regarding Schematik. ;;; 22-JUN-92 mk Updated SOAR entry. ;;; 24-JUN-92 mk Fixed MCL entry to note that CLIM is available ;;; from ILA, not via Apple. ;;; 25-JUN-92 mk 1.22 Added question [2-18]. ;;; 17-JUL-92 mk Added entry on PSD (Portable Scheme Debugger). ;;; 20-JUL-92 mk Updated entry on T3.1 ;;; 30-JUL-92 mk Added entry on XIT to question 2-2. ;;; 3-AUG-92 mk Updated PC-Scheme entry (bought by Ibuki). ;;; 6-AUG-92 mk 1.23 Merged in Jeff Dalton's pitfalls list. ;;; ------------------------------------------------------------ ;;; *EOF* Path: think.com!zaphod.mps.ohio-state.edu!uwm.edu!ogicse!das-news.harvard.edu!cantaloupe.srv.cs.cmu.edu!crabapple.srv.cs.cmu.edu!mkant From: mkant+@cs.cmu.edu (Mark Kantrowitz) Newsgroups: comp.lang.lisp,news.answers Subject: FAQ: Lisp Frequently Asked Questions 2/5 [Monthly posting] Summary: Frequently asked questions about Lisp -- General Questions Message-ID: Date: 14 Aug 92 00:38:07 GMT Article-I.D.: cs.lisp-faq-2.text_713752657 Expires: Sun, 27 Sep 1992 00:37:37 GMT Sender: news@cs.cmu.edu (Usenet News System) Reply-To: lisp-faq@think.com Followup-To: poster Organization: School of Computer Science, Carnegie Mellon Lines: 1215 Approved: news-answers-request@MIT.Edu Supersedes: Nntp-Posting-Host: a.gp.cs.cmu.edu Xref: think.com comp.lang.lisp:8024 news.answers:2526 Archive-name: lisp-faq/part2 Last-Modified: Thu Aug 6 11:54:55 1992 by Mark Kantrowitz Version: 1.23 ;;; **************************************************************** ;;; Answers to Frequently Asked Questions about Lisp *************** ;;; **************************************************************** ;;; Written by Mark Kantrowitz and Barry Margolin ;;; lisp-faq-2.text -- 63485 bytes This post contains Part 2 of the Lisp FAQ. If you think of questions that are appropriate for this FAQ, or would like to improve an answer, please send email to us at lisp-faq@think.com. Topics Covered (Part 2): [2-0] What FTP resources are available? [2-1] Is there a GNU-Emacs interface to Lisp? [2-2] How can I use the X Window System or other GUIs from Lisp? [2-3] When is it right to use EVAL? [2-4] What is the equivalent of EXPLODE and IMPLODE in Common Lisp? [2-5] Is Lisp inherently slower than more conventional languages such as C? [2-6] Why does my program's behavior change each time I use it? [2-7] Why does Common Lisp have "#'"? [2-8] How do I call non-Lisp functions from Lisp? [2-9] Can I call Lisp functions from other languages? [2-10] I want to call a function in a package that might not exist at compile time. How do I do this? [2-11] What is CDR-coding? [2-12] What is garbage collection? [2-13] How do I save an executable image of my loaded Lisp system? How do I run a Unix command in my Lisp? How do I get the current directory name from within a Lisp program? [2-14] I'm porting some code from a Symbolics Lisp machine to some other platform, and there are strange characters in the code. What do they mean? [2-15] History: Where did Lisp come from? [2-16] How do I find the argument list of a function? [2-17] How can I have two Lisp processes communicate via unix sockets? [2-18] When producing formatted output in Lisp, where should you put the newlines (e.g., before or after the line, FRESH-LINE vs TERPRI, ~& vs ~% in FORMAT)? Search for [#] to get to question number # quickly. ---------------------------------------------------------------- [2-0] What FTP resources are available? There are several repositories of publicly redistributable and public domain Lisp and Scheme code. FTP sites for Lisp/Scheme interpreters and compilers are discussed in the answer to question [4-0]. See the entry on Macintosh Common Lisp in question [4-0] for information on the CD-ROM of Lisp code that Apple distributes with MCL 2.0. The Lisp Utilities collection is accessible by anonymous ftp to any CMU CS machine (e.g., ftp.cs.cmu.edu [128.2.206.173]) or through AFS in the directory /afs/cs.cmu.edu/user/mkant/Public/Lisp-Utilities/ If accessing this directory through anonymous ftp, it is important to "cd" to the directory using one atomic operation, as some of the superior directories on the path are protected from access by an anonymous ftp. Files included in the repository include: extensions.lisp A collection of extensions to Common Lisp. initializations.lisp Brad Miller's initializations packaged for Allegro CL 4.0. xref.lisp Portable cross referencing tool for Lisp. Similar to the Symbolics Who-Calls and the Xerox MasterScope programs. defsystem.lisp Portable system definition facility (a "Make" for lisp). More featureful than other defsystem implementations. logical-pathnames.lisp Portable implementation of the X3J13 June 1989 specification for logical pathnames. metering.lisp Portable code time/space profiling tool. source-compare.lisp A portable "diff" utility for Lisp. user-manual.lisp Program which helps with documenting Lisp code. psgraph.lisp Joe Bates' PostScript DAG grapher. matcher.lisp A regexp-like matcher for Lisp. framework.lisp A portable generic frame system. date-formatter.lisp Simple code for formatting a date. save-object.lisp Kerry Koitzsch's package to save ASCII representations of Lisp objects to a file. defpackage.lisp Stephen Nicoud's semi-portable CLtL2 version of defpackage. johnson-yacc.lisp Mark Johnson's lisp YACC. ops5.tar.Z Public domain Common Lisp implementation of the OPS5 production system interpreter. "Expert System Shell". Written by Charles Forgy and ported by George Wood and Jim Kowalski. cmu-loop.lisp Implements the CLtL2 Loop Macro. mit-loop.lisp Implements the CLtL1 Loop Macro. sloop.lisp William Schelter's loop macro, not CLtL. yloop.lisp Frank Ritter and Jim Panagos' implementation of the Yale loop macro described in McDermont, Charniak and Riesbeck's AI programming book. Not CLtL. ew/ Express Windows distribution. iterate/ The Iterate Macro. series/ Waters' Series Macro package. simplex.lisp Bruno Haible's implementation of the Simplex algorithm. mapforms.tar.Z Moon's code walker. resources.lisp Brad Miller's resources package. nregex.lisp Lawrence Freil's regular expression matching code The Lisp Utilities repository is maintained by Mark Kantrowitz, cl-utilities-request@cs.cmu.edu. The Scheme Repository contains a Scheme bibliography, copies of the R4RS report and other papers, sample Scheme code for a variety of purposes, several utilities, and some implementations. The repository is maintained by Ozan S. Yigit, scheme@nexus.yorku.ca. The repository is accessible by anonymous ftp at nexus.yorku.ca [130.63.9.66] in the directory pub/scheme/. Scheme Implementations may also be found at altdorf.ai.mit.edu:/archive/ The R4RS reports is available in altdorf.ai.mit.edu:/archive/scheme-reports/ or as MIT AI Memo 848b (email publications@ai.mit.edu for more information). PSD (Portable Scheme Debugger) is available by anonymous ftp from Tampere University of Technology, Finland, cs.tut.fi:/pub/src/languages/schemes/psd.tar.Z With PSD, you can run a Scheme program in an Emacs buffer, set breakpoints, single step evaluation and access and modify the program's variables. It works by instrumenting the original source code, so it should run with any R4RS compliant Scheme. It has been tested with SCM and Elk 1.5, but should work with other Schemes with a minimal amount of porting, if at all. Includes documentation and user's manual. Written by Pertti Kellom\"aki, pk@cs.tut.fi The Macintosh Common Lisp repository contains Lisp code for MCL contributed by MCL users. It is available by anonymous ftp from cambridge.apple.com:pub/MACL/CONTRIB [134.149.2.3] and also contains the Info-MCL mailing list archives. MIT AI Lab -- ftp.ai.mit.edu:pub/ loop-macro.tar [LOOP from CLtL] series/ [SERIES from CLtL2] Iterate/ [Alternative to series and loop.] clmath.tar [Numeric math 1984] ontic/ [ONTIC Knowledge Rep. for Mathematics] xp/ [Waters' XP Lisp Pretty Printer] The LispUsers Archives, a collection of programs for Medley, can be found on nervous.cis.ohio-state.edu:pub/lispusers/medley. Also on nervous.cis.ohio-state.edu is GTT, an implementation of Chandrasekaran's Generic Tasks Toolset, in directory pub/lispusers/toolset. There's a repository of Amiga LISP (and Lisp-like language) implementations on gatekeeper.pa.dec.com:pub/micro/amiga/lisp/. Common Lisp versions of the mini programs from "Inside Computer Understanding" by Schank and Riesbeck, 1981, are available by anonymous ftp from cs.umd.edu in the directory pub/schank. Contact Bill Andersen (waander@cs.umd.edu) for more information. The directory pub/schank/icbr contains the complete code for "Inside Case-Based Reasoning" by Riesbeck and Schank, 1989. This includes code for an instructional version of CHEF by Kristian Hammond. Norvig: The software from Peter Norvig's book "Paradigms of AI Programming" is available by anonymous ftp from unix.sri.com:pub/norvig and on disk in Macintosh or DOS format from the publisher, Morgan Kaufmann. | Software includes Common Lisp implementations of: Eliza and pattern matchers, Emycin, Othello, Parsers, Scheme interpreters and compilers, Unification and a prolog interpreter and compiler, Waltz line-labelling, implementation of GPS, macsyma, and random number generators. | For more information, contact: Morgan Kaufmann, Dept. P1, 2929 Campus Drive, Suite 260 San Mateo CA 94403, (800) 745-7323; FAX: (415) 578-0672 A catalog of free and commercial natural language software is available from the Natural Language Software Registry, by anonymous ftp from tira.uchicago.edu [128.135.96.31] in the directory /registry, or by email to registry@tira.uchicago.edu. Other sites contain specific programs: PCL -- parcftp.xerox.com:pcl/ [13.1.64.94] Portable Common Loops (PCL) is a portable implementation of the Common Lisp Object System (CLOS). Gabriel Lisp Benchmarks are available by anonymous ftp as ai.toronto.edu:/pub/gabriel-lisp-benchmarks.tar.Z. GLisp -- apple.com:/pub/dts/mac/lisp/glisp.tar.Z See also ftp.apple.com OBVIUS -- whitechapel.media.mit.edu:/pub/ [18.85.0.125] Object-Based Vision and Image Understanding System (OBVIUS), is a Common Lisp image processing package. Provides a library of image processing routines (e.g., convolutions, fourier transforms, statistical computations, etc.) on gray or binary images and image-sequences (no color support yet), an X windows display interface, postscript printer output, etc. It uses a homebrew interface to X11 (i.e., it does not use clx or clue). However, they eventually hope to port Obvius to a clx/clue platform. Written by David Heeger and Eero Simoncelli . Runs in Lucid-4.0. Includes LaTeX documentation and User's Guide. Scheme Utilities -- brokaw.lcs.mit.edu:/pub/scmutils.tar 18.30.0.33 GNU-Emacs -- prep.ai.mit.edu: TI Explorer Lisp Code -- sumex-aim.stanford.edu:pub/exp/ The Knowledge Systems Lab's set of Explorer patches and tools. It includes in the jwz subdirectory a set of tools written and collected by Jamie Zawinski. Send questions to acuff@sumex-aim.stanford.edu. StarLisp Simulator -- think.com:/cm/starlisp/starsim-f19-sharfile Simulates *Lisp, one of the programming langauges used to program the Connection Machine. Runs under Symbolics, Lucid, Allegro, and Franz. InterLisp->Common-Lisp Translator -- ai.sri.com:pub/pkarp/lisp/ilisp/ MCS (Meta Class System) -- ftp.gmd.de:/pub/lisp/mcs/ [129.26.8.90] Portable object-oriented extension to Common Lisp. Integrates the functionality of CLOS (the Common Lisp Object System), and TELOS, (the object system of LeLisp Version 16 and EULISP). MCS provides a metaobject protocol which the user can specialize. MCS is claimed to be more efficient in time and space than comparable systems we know, including commercial CLOS implementations. Runs in any valid Common Lisp. Contact: Harry Bretthauer and Juergen Kopp, German National Research Center for Computer Science (GMD), Expert System Research Group, P.O. Box 1316, D-5205 Sankt Augustin 1, FRG, email: kopp@gmdzi.gmd.de LMath -- peoplesparc.berkeley.edu:pub/mma.tar.Z [128.32.131.14] A Mathematica-style parser written in Common Lisp. Written by Richard Fateman; fateman@renoir.Berkeley.EDU. Runs in any valid Common Lisp. CLOS-on-KEE -- zaphod.lanl.gov:/pub/ A subset of CLOS that is implemented on top of KEE. Contact egdorf%zaphod@LANL.GOV (Skip Egdorf) for more info. ftp.csrl.aoyama.ac.jp: YY/ YY window toolkit sources Lisp/ several common lisp sources, including MIT's FRL. RRL (Rewrite Rule Laboratory) -- herky.cs.uiowa.edu:public/rrl [128.255.28.100] TMYCIN -- sumex-aix.stanford.edu:/tmycin The TMYCIN rule based system. NONLIN -- cs.umd.edu:/pub/nonlin (128.8.128.8) Common Lisp implementation of the NONLIN planning system originally designed and implemented by Austin Tate. Bugs can be reported to nonlin-bugs@cs.umd.edu. User's group is nonlin-users@cs.umd.edu. The authors request that anybody ftping the code send a message to nonlin-users-request@cs.umd.edu, letting them know you have a copy and also letting them know if you wish to subscribe to the users group. More information can also be obtained from Jim Hendler, hendler@cs.umd.edu. rascal.ics.utexas.edu:/pub/ 128.83.138.20 Maxima for Common Lisp (License required from National Energy Software Center at Argonne.) Ported by Bill Schelter. nqthm/ Boyer and Moore's theorem prover. Also available from cli.com:/pub/nqthm. proof-checker/ Matt Kaufmann's proof checking enhancements to nqthm. Eliza and similar programs. Besides Norvig's book, see: o The doctor.el is an implementation of Eliza for GNU-Emacs emacs-lisp. Invoke it with "Meta-X doctor" o Source code for ELIZA in Prolog (implemented by Viren Patel) is available by ftp from aisun1.ai.uga.edu. o muLISP-87 (a MSDOS Lisp sold by Soft Warehouse) includes a Lisp implementation of Eliza. o Compute!'s Gazette, June 1984, includes source for a BASIC implementation of Eliza. You can also find it in 101 more computer games, edited by David Ahl, published by Creative Computing (alas, they're defunct, and the book is out of print). o Herbert Schildt "Artificial Intelligence using C", McGraw-Hill, 1987, ISBN 0-07-881255-0, pp315-338, includes a simple version of DOCTOR. o ucsd.edu:pub/pc-ai contains implementations of Eliza for the IBM PC. BELIEF is a Common Lisp implementation of the Dempster and Kong fusion and propagation algorithm for Graphical Belief Function Models and the Lauritzen and Spiegelhalter algorithm for Graphical Probabilistic Models. It is available by anonymous ftp from ftp.stat.washington.edu (128.95.17.34), and by email from the author, Russell Almond . A Common Lisp implementation of ABTWEAK, a hierarchical nonlinear planner extending David Chapman's (MIT) TWEAK, may be obtained by anonymous ftp from csis.dit.csiro.au in the directory pub/steve. A user's manual, a copy of the associated masters thesis by Steve Woods, and an extended Journal paper are also contained in that directory. Send mail to Steven.Woods@csis.dit.csiro.au for more information. PLisp - A Common Lisp front end to Postscript. This translates many Common Lisp functions to postscript as well as manage the environment and many lispisms (&optional and &rest arguments, multiple values, macros, ...). Available via anonymous ftp in pub/plisp/plisp.tar.Z on nebula.cs.yale.edu (128.36.13.1). Written by John Peterson, peterson-john@cs.yale.edu. Frame Languages: o FrameWork is available in the Lisp Utilities Repository described above. o Theo (learning frame system) is available free from CMU, after signing a license agreement. Send mail to Tom.Mitchell@cs.cmu.edu. o FrameKit is available free from CMU, after signing a license agreement. Send mail to Eric.Nyberg@cs.cmu.edu o KR. Send mail to Brad.Myers@cs.cmu.edu for more info. o PARMENIDES (Frulekit) is available free, after signing a license agreement. Send mail to peter.shell@cs.cmu.edu o FROBS is available free by anonymous ftp from cs.utah.edu:/pub/frobs.tar.Z Contact Robert Kessler for more info. o PFC is a simple frame system written by Tim Finin available free by anonymous ftp from linc.cis.upenn.edu. o YAK is a hybrid knowledge-representation system of the KL-ONE family. Includes an optional graphical interface depending on the Lisp. Available free after signing a license agreement. Contact Enrico Franconi . The UMass GBB system (V1.2) is available by anonymous ftp from dime.cs.umass.edu:/gbb. The commercial GBB product is not. Work on the UMass GBB project (and funding) ended over 2 years ago. Many researchers using it have opted for the commercial release. The UMass research system remains available, but the two should not be confused as the commercial system is substantially improved and extended. The commercial system is available from Blackboard Technology Group, PO Box 44, 401 Main Street, Amherst, Massachusetts 01002, 413-256-4240. MVL (Multi-Valued Logic) is a theorem proving system written in Common Lisp, and is available from t.stanford.edu:/mvl/mvl.tar.Z A user's manual may be found in /mvl/manual.tex. Send mail to ginsberg@t.stanford.edu. Postgres is an object-oriented database, and is available from postgres.berkeley.edu:/pub/postgres* It runs on DecStation 3100s, Sun3 (SunOs), Sun4 (Sparc), and Sequent Symmetry. CL-Protos is a Common Lisp implementation of the case-based reasoning system developed by E. Ray Bareiss and Bruce W. Porter of the University of Texas/Austin AI Lab. It runs on Sun3, TI Explorer, HP 9000, and Symbolics, and gobbles a huge amount of memory. Common Lisp implementation by Rita Duran, Dan Dvorak, Jim Kroger, Hilel Swerdlin, and Ben Tso. For more information, bug reports, or comments, contact either Dan Dvorak or Ray Bareiss or Erik Eilerts Available by anonymous ftp from cs.utexas.edu:/pub/porter QSIM is a qualitative reasoning system implemented in Common Lisp. It is available by anonymous ftp from cs.utexas.edu:/pub/qsim ID3. A Lisp implementation of ID3 and other machine learning algorithms is available by anonymous ftp from the machine learning group at the University of Texas as cs.utexas.edu:pub/mooney RHETORICAL is a planning and knowledge tool available by anonymous ftp from cs.rochester.edu:/pub/knowledge-tools in the files rhet-19-40.tar.Z and cl-lib-3-11.tar.Z. The files tempos-3-6.tar.Z and timelogic-5-0.tar.Z add James Allen's interval logic to Rhet. It runs on Symbolics Genera and Allegro Common Lisp. Written by Brad Miller . KNOWBEL is an implementation of Telos (a sorted/temporal logic system) by Bryan M. Kramer, . It is available by anonymous ftp from ai.toronto.edu:/pub/kr/ as the files knowbel.tar.Z and manual.txt.tar.Z Runs in Allegro CL on Sparcstations and Silicon Graphics 4d and in MCL on Apple Macintoshes. SNePS is a semantic net implementation, available free after signing a license agreement. Contact shapiro@cs.buffalo.edu for more information. PRODIGY is an integrated planning and learning system, available free after signing a license agreement. Contact prodigy@cs.cmu.edu for more information. SOAR is an integrated intelligent agent architecture currently being developed at Carnegie Mellon University, the University of Michigan, and the Information Sciences Institute of the University of Souther California. Soar, and its companion systems, CParaOPS5 and TAQL, have been placed in the public domain. The system may be retrieved by anonymous ftp to ftp.cs.cmu.edu (or any other CMU CS machine) in the directory /afs/cs.cmu.edu/project/soar/5.2/2/public/. [Note: You must cd to this directory in one atomic operation, as superior directories may be protected during an anonymous ftp.] For more information, send email to soar-request@cs.cmu.edu or write to The Soar Group, School of Computer Science, Carnegie Mellon University, Pittsburgh, PA 15213. Finally, though the software is in the public domain, the manual remains under copyright. To obtain one (at no charge) send a request (including your physical mail address) to soar-doc@cs.cmu.edu or to the physical address above. RegExp is an extension to Allegro Common Lisp which adds regular expression string matching, using the foreign function interface. Available by anonymous ftp from ai.sri.com:/pub/pkarp/regexp/. Contact pkarp@ai.sri.com for more information. SNLP is a domain independent systematic nonlinear planner, available by anonymous ftp from cs.washington.edu:/pub/snlp.tar.Z Contact weld@cs.washington.edu for more information. TILEWORLD is a planning testbed/simulator developed at SRI International by Martha Pollack, Michael Frank and Marc Ringuette. TILEWORLD originally ran under Lucid CL, but was later extended and ported to Allegro CL by Badr H. Al-Badr and Steve Hanks. The new tileworld is available by anonymous ftp from cs.washington.edu as the file new-tileworld.tar.Z It includes an X interface. TRUCKWORLD is a simulated world intended to provide a testbed for AI planning programs, where the planning agent is a truck that roams around the simulated world. It is available by anonymous ftp from cs.washington.edu in the file simulator.tar.Z. It includes an X interface. Contact Steve Hanks for more information. COBWEB/3 is a concept formation system available free after signing a license agreement. Contact cobweb@ptolemy.arc.nasa.gov for more information. VEOS (Virtual Environment Operating Shell) is an extendible environment for prototyping distributed applications for Unix. The programmer's interface uses XLISP 2.1. Although intended for distributed Virtual Reality applications at The Human Interface Technology Lab in Seattle, it should be appropriate for other applications. VEOS uses heavyweight sequential processes, corresponding roughly to unix processes. VEOS runs on DEC/5000, Sun4, and Silicon Graphics VGX and Indigo. VEOS is available by anonymous ftp from milton.u.washington.edu (128.95.136.1) in the directory ~ftp/public/veos as veos.tar.Z. If you use the software, the authors ask that you send them mail to veos-support@hitl.washington.edu. PAIL (Portable AI Lab) is a computing environment containing a collection of state-of-the-art AI tools, examples, and documentation. It is aimed at those involved in teaching AI courses at university level or equivalent. The system has enough built-in functionality to enable its users to get practical experience with a broad range of AI problems without having to build all the supporting tools from scratch. It is implemented in Common Lisp and uses CLOS and Allegro Common Windows (i.e., in Allegro CL 4.1). It is available by anonymous ftp from pobox.cscs.ch:/pub/ai/pail-2.1/. Written by Mike Rosner and Dean Allemang {dean,mike}@idsia.ch. XSTAT is a statistics package which runs in XLISP. It has recently been ported to Common Lisp, and is available as umnstat.stat.umn.edu:/pub/xlispstat/CL/CLS1.0A1.tar.Z The CL port does not yet include the lisp-stat dynamic graphics package, only the numerics. IDM is a Common Lisp implementation of both a classical and extended version of the STRIPS planner. It is available by anonymous ftp from sauquoit.gsfc.nasa.gov (128.183.101.29). Questions, comments and bug reports may be sent to idm-users@chelmsford.gsfc.nasa.gov. ---------------------------------------------------------------- [2-1] Is there a GNU-Emacs interface to Lisp? ILISP is a powerful GNU-Emacs interface to many dialects of Lisp, including Lucid, Allegro, {A}KCL, IBCL, and CMU. Written by Chris McConnell . It is available by anonymous ftp from katmandu.mt.cs.cmu.edu [128.2.250.68] in the directory pub/ilisp as the file ilisp.tar.Z. If you start using it, send Chris mail, as he maintains a mailing list of users. Franz Inc.'s GNU-Emacs/Lisp interface includes an online Common Lisp manual. It is available by license from Franz Inc. Contact info@franz.com for more information. There is also a mailing list, lisp-emacs-forum-request@ucbarpa.berkeley.edu. The cl-shell package provides a major mode (cl-shell-mode) for running Common Lisp (CL) as an Emacs subprocess. It provides a general mechanism for communication between CL and Emacs which does not rely on extra processes, and should therefore be easily portable to any version of CL. Features include direct (i.e., not through a temp file) evaluation and in-package compilation of forms from lisp-mode buffers, type-ahead and a history mechanism for the cl-shell buffer, and pop-up help facilities for the CL functions documentation, macroexpand and describe. Extensions for Lucid Common Lisp provide pop-up arglists and source file editing. Other extensions are provided to allow editing source files of CLOS or Flavors methods. Cl-shell is available on the Lucid tape (in the goodies directory) or via anonymous ftp from whitechapel.media.mit.edu (18.85.0.125). Lucid includes some other Emacs-Lisp interfaces in its goodies directory. Harlequin's LispWorks includes an Emacs-Lisp interface. Venue's Medley has an optional EMACS Interface. ---------------------------------------------------------------- [2-2] How can I use the X Window System or other GUIs from Lisp? There are several GUI's and Lisp interfaces to the X Window System. Mailing lists for these systems are listed in the answer to question [4-2]. Various vendors also offer their own interface-building packages. CLX provides basic Common Lisp/X functionality. It is a de facto standard low-level interface to X, providing equivalent functionality to XLib, but in Lisp. It is also a good source for comparing the foreign function calls in various Lisps. Does *not* depend on CLOS. Available free as part of the X release in the contrib directory. Also available form export.lcs.mit.edu:/contrib as the files CLX.Manual.tar.Z, CLX.R4.5.tar.Z and CLX.R5.tar.Z Primary Interface Author: Robert W. Scheifler Send bug reports to bug-clx@expo.lcs.mit.edu. CLIM (Common Lisp Interface Manager) is a GUI originally developed by Symbolics and International Lisp Associates, and now under joint development by several Lisp vendors, including Symbolics, Apple, Franz, Harlequin and Lucid. It is intended to be a portable analogue of Symbolics UIMS (Dynamic Windows, Presentations Types). It runs on Symbolics Lisp Machines; Allegro and Lucid on several Unix platforms; Symbolics CLOE on 386/486 IBM PCs running Windows; and MCL on Apple Macintoshes. It is *not* free, and with the exception of Macintoshes, if it is available it can be purchased from the vendor of the Lisp system you are using. For the Macintosh version write to the ILA: International Lisp Associates, 114 Mt. Auburn St., Cambridge, MA 02138, 617-576-1151 Contact: Dennis Doughty - Doughty@ILA.com International Lisp Associates, 898 Windmill Park Road, Mountain View, CA 94043, 1-800-477-CLIM Contact: Bill York - York@ILA.com The CLIM 2.0 SPECIFICATION is available by anonymous ftp from ftp.uunet.net:vendor/franz/clim.ps.Z. CLUE (Common Lisp User-Interface Environment) is from TI, and extends CLX to provide a simple, object-oriented toolkit (like Xt) library that uses CLOS. Provides basic window classes, some stream I/O facilities, and a few other utilities. Still pretty low level (it's a toolkit, not widget library). Available free by anonymous ftp from csc.ti.com:pub/clue.tar.Z Written by Kerry Kimbrough. Send bug reports to clue-bugs@dsg.csc.ti.com. CLIO (Common Lisp Interactive Objects) is a GUI from the people who created CLUE. It provides a set of CLOS classes that represent the standard components of an object-oriented user interface -- such as text, menus, buttons, scroller, and dialogs. It is included as part of the CLUE distribution, along with some packages that use it, both sample and real. Allegro Common Windows provides a front end to CLX. Uses CLOS. It is *not* free. Contact info@franz.com for more information. The LispWorks Toolkit is an extensible CLOS-based widget set that uses CLX and CLUE. The LispWorks programming environment has been written using the toolkit and includes: an Emacs-like editor, listener, debugger, profiler, and operating system shell; browsers/graphers for classes, generic functions, processes, windows, files, compilation errors, source code systems, and setting LispWorks parameters; and an interactive interface builder and complete online hypertext documentation. Contact: lispworks-request@harlqn.co.uk CLM (Common Lisp Motif) and GINA (Generic Interactive Application) and IB (Interface Builder). CLM runs Motif widgets in a separate C process, with minimal work on the Lisp side and communicates between C and Lisp using TCP sockets. Runs in Allegro CL, Sun CL, and Symbolics Genera. GINA uses CLOS. Available free in the X contrib directory or by anonymous ftp from either export.lcs.mit.edu:/contrib or ftp.gmd.de:/gmd/gina [129.26.8.90] as the files CLM+GINA.README, CLM2.1.tar.Z and GINA2.1.tar.Z. CLM was written by Andreas Baecker , GINA by Mike Spenke , and IB by Thomas Berlage . Contact Mike Spenke for more info. EW (Express Windows) is intended to mimic Symbolics' Dynamic Windows user and programmer interfaces. It is available free in the ew/ subdirectory of the Lisp Utilities repository. It is no longer under active development. Runs on Sun/Lucid, Franz Allegro, and Symbolics. Should port easily to other Lisps with CLX. Written by Andrew L. Ressler . Garnet is a large and flexible GUI. Lots of high-level features. Does *not* depend on CLOS, but does depend on CLX. Garnet (version 2.0 and after) is now in the public domain, and has no licensing restrictions, so it is available to all foreign sites and for commercial uses. Detailed instructions for obtaining it by anonymous ftp are available by anonymous ftp from a.gp.cs.cmu.edu [128.2.242.7] as the file /usr/garnet/garnet/README. Garnet includes the Lapidiary interactive design tool, Gilt Interface Builder, automatic display management, two widget sets (Motif look-and-feel and Garnet look-and-feel), support for gesture recognition, and automatic constraint maintenance, application data layout and PostScript generation. Runs in virtually any Common Lisp environment, including Allegro, Lucid, CMU, and Harlequin Common Lisps on Sun, DEC, HP, Apollo, IBM 6000, and many other machines. Garnet helps implement highly-interactive, graphical, direct manipulation programs for X/11 in Common Lisp. Typical applications include: drawing programs similar to Macintosh MacDraw, user interfaces for expert systems and other AI applications, box and arrow diagram editors, graphical programming languages, game user interfaces, simulation and process monitoring programs, user interface construction tools, CAD/CAM programs, etc. Contact Brad Myers (bam@a.gp.cs.cmu.edu) for more information. Bug reports and administrative questions: garnet@cs.cmu.edu. LispView is a GUI written at Sun that does not use CLX. Instead it converts Xlib.h directly into Lucid foreign function calls. It is intended to be fast and tight. Uses CLOS. Available for anonymous ftp from export.lcs.mit.edu:contrib/lispview1.1 and xview.ucdavis.edu:pub/XView/LispView1.1 Includes a general-purpose 2D grapher library. Written by Hans Muller (hmuller@sun.com). Runs in Sun CL and Lucid CL. Direct questions about the source provision to lispview@Eng.Sun.Com. WINTERP (Widget INTERPreter) was developed at HP and uses the Xtoolkit and Motif widget set. It is based on David Betz's XLISP interpreter, which is a small subset of Common Lisp that runs on IBM PCs. Runs on DecStation 3100, HP9000s, Sun3, Sparcs. It is a free-standing Lisp-based tool for setting up window applications. Available free in X contrib directory, or by anonymous ftp from export.lcs.mit.edu:contrib/winterp-???.tar.Z where ??? is the version number. If you do not have Internet access you may request the source code to be mailed to you by sending a message to winterp-source%hplnpm@hplabs.hp.com or hplabs!hplnpm!winterp-source. Contact Niels Mayer mayer@hplabs.hp.com for more information. YYonX is a port of the YY system to X windows. Runs in Lucid CL, Allegro CL, and Symbolics Genera. Supports kanjii. Developed at Aoyama Gakuin University. Available free by anonymous ftp from ftp.csrl.aoyama.ac.jp:YY/ Written by Masayuki Ida Picasso is a CLOS based GUI, and is available from postgres.berkeley.edu:/pub/Picasso-2.0 It runs on DecStation 3100s, Sun3 (SunOs), Sun4 (Sparc), and Sequent Symmetry in Allegro CL. The file pub/xcl.tar.Z contains X-Common Lisp interface routines. Send mail to picasso@postgres.berkeley.edu for more information. XIT (X User Interface Toolkit) is an object-oriented user interface toolkit for the X Window System based on Common Lisp, CLOS, CLX, and CLUE. It has been developed by the Research Group DRUID at the Department of Computer Science of the University of Stuttgart as a framework for Common Lisp/CLOS applications with graphical user interfaces for the X Window System. The work is based on the USIT system developed by the Research Group INFORM at the University of Stuttgart. Although the system kernel is quite stable, XIT is still under active development. XIT can be obtained free by anonymous ftp from ifi.informatik.uni-stuttgart.de (129.69.211.1) in the directory /pub/xit/. ---------------------------------------------------------------- [2-3] When is it right to use EVAL? Hardly ever. Any time you think you need to use EVAL, think hard about it. EVAL is useful when implementing a facility that provides an external interface to the Lisp interpreter. For instance, many Lisp-based editors provide a command that prompts for a form and displays its value. Inexperienced macro writers often assume that they must explicitly EVAL the subforms that are supposed to be evaluated, but this is not so; the correct way to write such a macro is to have it expand into another form that has these subforms in places that will be evaluated by the normal evaluation rules. Explicit use of EVAL in a macro is likely to result in one of two problems: the dreaded "double evaluation" problem, which may not show up during testing if the values of the expressions are self-evaluating constants (such as numbers); or evaluation at compile time rather than runtime. For instance, if Lisp didn't have IF and one desired to write it, the following would be wrong: (defmacro if (test then-form &optional else-form) ;; this evaluates all the subforms at compile time, and at runtime ;; evaluates the results again. `(cond (,(eval test) ,(eval then-form)) (t ,(eval else-form)))) (defmacro if (test then-form &optional else-form) ;; this double-evaluates at run time `(cond ((eval ,test) (eval ,then-form)) (t (eval ,else-form))) This is correct: (defmacro if (test then-form &optional else-form) `(cond (,test ,then-form) (t ,else-form))) On the other hand, EVAL can sometimes be necessary when the only portable interface to an operation is a macro. ---------------------------------------------------------------- [2-4] What is the equivalent of EXPLODE and IMPLODE in Common Lisp? Hopefully, the only reason you need to do this is as part of trying to port some old MacLisp code to Common Lisp. These functions predated the inclusion of strings as a first-class data type in Lisp; symbols were used as strings, and they ere EXPLODEd to allow the individual characters to be manipulated in a list. Probably the best approximations of these are: (defun explode (object) (loop for char across (prin1-to-string object) collect (intern (string char)))) (defun implode (list) (read-from-string (coerce (mapcar #'character list) 'string))) An alternate definition of EXPLODE which uses MAP instead of LOOP is: (defun explode (object) (map 'list #'(lambda (char) (intern (string char))) (prin1-to-string object))) The creation of N conses of garbage to process a string of N characters is a hideously inefficient way of doing the job. Rewrite EXPLODE code with PRIN1-TO-STRING, or better STRING if the arguments are symbols without funny characters. For IMPLODE, try to make its caller use strings and try to make the result usable as a string to avoid having to call INTERN or READ-FROM-STRING. ---------------------------------------------------------------- [2-5] Is Lisp inherently slower than more conventional languages such as C? This is a tough question to answer, as I'm sure you expected. In many cases, it appears to be. Lisp does not require the programmer to specify the data type of variables, so generic arithmetic operators may have to perform type checking at runtime in order to determine how to proceed. However, Lisp code can also be dense (i.e. there is more expressed in a single line) than many other languages: the Lisp expression (+ A B) is more powerful than the C expression A+B (the Lisp version supports bignums, rationals, and complex numbers, while the C version only supports limited-size integers and floating point); therefore, one may claim that it is reasonable that the Lisp version take longer than the C version (but don't expect everyone to accept this rationalization). Solutions to this include hardware support (e.g. processors that support type tags in data, such as SPARC and Symbolics Lisp Machines), declarations, and specialized variants of functions (e.g. in MacLisp, + accepts and returns only fixnums, +$ accepts and returns only flonums, and PLUS is generic). At one time, the MIT PDP-10 MacLisp compiler was compared to DEC's PDP-10 Fortran compiler. When appropriate declarations were supplied in the Lisp code, the performance of compiled Lisp arithmetic rivaled that of the Fortran code. It would hardly be fair to compare Lisp without declarations to Fortran, since the Fortran compiler would have more information upon which it could base its optimizations. Since Lisp is a good language for rapid prototyping, it is easy for a mediocre programmer (or even a good programmer, who isn't being careful) to generate a large amount of inefficient Lisp code. A good example is the use of APPEND to link successive lists together, instead of keeping a pointer to the tail of the list. Often a programmer can obtain significant speed increases by using a time/space profiler to identify the functions which waste time (often small functions which are called frequently) and rewriting those functions. ---------------------------------------------------------------- [2-6] Why does my program's behavior change each time I use it? Most likely your program is altering itself, and the most common way this may happen is by performing destructive operations on embedded constant data structures. For instance, consider the following: (defun one-to-ten-except (n) (delete n '(1 2 3 4 5 6 7 8 9 10))) (one-to-ten-except 3) => (1 2 4 5 6 7 8 9 10) (one-to-ten-except 5) => (1 2 4 6 7 8 9 10) ; 3 is missing The basic problem is that QUOTE returns its argument, *not* a copy of it. The list is actually a part of the lambda expression that is in ONE-TO-TEN-EXCEPT's function cell, and any modifications to it (e.g., by DELETE) are modifications to the actual object in the function definition. The next time that the function is called, this modified list is used. In some implementations calling ONE-TO-TEN-EXCEPT may even result in the signalling of an error or the complete aborting of the Lisp process. Some Lisp implementations put self-evaluating and quoted constants onto memory pages that are marked read-only, in order to catch bugs such as this. Details of this behavior may vary even within an implementation, depending on whether the code is interpreted or compiled (perhaps due to inlined DEFCONSTANT objects). All of these behaviors are allowed by the draft ANSI Common Lisp specification, which specifically states that the consequences of modifying a constant are undefined (X3J13 vote CONSTANT-MODIFICATION:DISALLOW). To avoid these problems, use LIST to introduce a list, not QUOTE. QUOTE should be used only when the list is intended to be a constant which will not be modified. If QUOTE is used to introduce a list which will later be modified, use COPY-LIST to provide a fresh copy. For example, the following should all work correctly: o (remove 4 (list 1 2 3 4 1 3 4 5)) o (remove 4 '(1 2 3 4 1 3 4 5)) ;; Remove is non-destructive. o (delete 4 (list 1 2 3 4 1 3 4 5)) o (let ((x (list 1 2 4 1 3 4 5))) (delete 4 x)) o (defvar *foo* '(1 2 3 4 1 3 4 5)) (delete 4 (copy-list *foo*)) (remove 4 *foo*) (let ((x (copy-list *foo*))) (delete 4 x)) The following, however, may not work as expected: o (delete 4 '(1 2 3 4 1 3 4 5)) ---------------------------------------------------------------- [2-7] Why does Common Lisp have "#'"? #' is a macro-character which expands #'FOO to (FUNCTION FOO). Symbols in Lisp have two bindings, one for values and one for functions, allowing them to represent both variables and functions, depending on context. #'FOO accesses FOO's lexical function binding in a context where the value interpretation would normally occur. #' is also used to create lexical closures for lambda expressions. A lexical closure is a function which when invoked executes the body of the lambda-expression in the lexical environment within which the closure was created. See pp. 115-117 of CLtL2 for more details. ---------------------------------------------------------------- [2-8] How do I call non-Lisp functions from Lisp? Most Lisp implementations for systems where Lisp is not the most common language provide a "foreign function" interface. As of now there has been no significant standardization effort in this area. They tend to be similar, but there are enough differences that it would be inappropriate to try to describe them all here. In general, one uses an implementation-dependent macro that defines a Lisp function, but instead of supplying a body for the function supplies the name of a function written in another language; the argument list portion of the definition is generally augmented with the data types the foreign function expects and the data type of the foreign function's return value, and the Lisp interface function arranges to do any necessary conversions. There is also generally a function to "load" an object file or library compiled in a foreign language, which dynamically links the functions in the file being loaded into the address space of the Lisp process, and connects the interface functions to the corresponding foreign functions. If you need to do this, see the manual for your language implementation for full details. In particular, be on the lookout for restrictions on the data types that may be passed. You may also need to know details about the linkage conventions that are used on your system; for instance, many C implementations prepend an underscore onto the names of C functions when generating the assembler output (this allows them to use names without initial underscores internally as labels without worrying about conflicts), and the foreign function interface may require you to specify this form explicitly. Franz Allegro Common Lisp's "Foreign Function Call Facility" is described in chapter 10 of the documentation. Calling Lisp Functions from C is treated in section 10.8.2. The foreign function interface in Macintosh Common Lisp is similar. The foreign function interface for KCL is described in chapter 10 of the KCL Report. The foreign function interfaces for Lucid on the Vax and Lucid on the Sun4 are incompatible. Lucid's interface is described in chapter 5 of the Advanced User's Guide. ---------------------------------------------------------------- [2-9] Can I call Lisp functions from other languages? In implementations that provide a foreign function interface as described above, there is also usually a "callback" mechanism. The programmer may associate a foreign language function name with a Lisp function. When a foreign object file or library is loaded into the Lisp address space, it is linked with these callback functions. As with foreign functions, the programmer must supply the argument and result data types so that Lisp may perform conversions at the interface. ---------------------------------------------------------------- [2-10] I want to call a function in a package that might not exist at compile time. How do I do this? Use (funcall (find-symbol "SYMBOL-NAME" :pkg-name) ...). ---------------------------------------------------------------- [2-11] What is CDR-coding? CDR-coding is a space-saving way to store lists in memory. It is normally only used in Lisp implementations that run on processors that are specialized for Lisp, as it is difficult to implement efficiently in software. In normal list structure, each element of the list is represented as a CONS cell, which is basically two pointers (the CAR and CDR); the CAR points to the element of the list, while the CDR points to the next CONS cell in the list or NIL. CDR-coding takes advantage of the fact that most CDR cells point to another CONS, and further that the entire list is often allocated at once (e.g. by a call to LIST). Instead of using two pointers to implement each CONS cell, the CAR cell contains a pointer and a two-bit "CDR code". The CDR code may contain one of three values: CDR-NORMAL, CDR-NEXT, and CDR-NIL. If the code is CDR-NORMAL, this cell is the first half of an ordinary CONS cell pair, and the next cell in memory contains the CDR pointer as described above. If the CDR code is CDR-NEXT, the next cell in memory contains the next CAR cell; in other words, the CDR pointer is implicitly thisaddress+1, where thisaddress is the memory address of the CAR cell. If the CDR code is CDR-NIL, then this cell is the last element of the list; the CDR pointer is implicitly a reference to the object NIL. When a list is constructed incrementally using CONS, a chain of ordinary pairs is created; however, when a list is constructed in one step using LIST or MAKE-LIST, a block of memory can be allocated for all the CAR cells, and their CDR codes all set to CDR-NEXT (except the last, which is CDR-NIL), and the list will only take half as much storage (because all the CDR pointers are implicit). If this were all there were to it, it would not be difficult to implement in software on ordinary processors; it would add a small amount of overhead to the CDR function, but the reduction in paging might make up for it. The problem arises when a program uses RPLACD on a CONS cell that has a CDR code of CDR-NEXT or CDR-NIL. Normally RPLACD simply stores into the CDR cell of a CONS, but in this case there is no CDR cell -- its contents are implicitly specified by the CDR code, and the word that would normally contain the CDR pointer contains the next CONS cell (in the CDR-NEXT case) to which other data structures may have pointers, or the first word of some other object (in the CDR-NIL case). When CDR-coding is used, the implementation must also provide automatic "forwarding pointers"; an ordinary CONS cell is allocated, the CAR of the original cell is copied into its CAR, the value being RPLACD'ed is stored into its CDR, and the old CAR cell is replaced with a forwarding pointer to the new CONS cell. Whenever CAR or CDR is performed on a CONS, it must check whether the location contains a forwarding pointer. This overhead on both CAR and CDR, coupled with the overhead on CDR to check for CDR codes, is generally enough that using CDR codes on conventional hardware is infeasible. There is some evidence that CDR-coding doesn't really save very much memory, because most lists aren't constructed at once, or RPLACD is done on them enough that they don't stay contiguous. At best this technique can save 50% of the space occupied by CONS cells. However, the savings probably depends to some extent upon the amount of support the implementation provides for creating CDR-coded lists. For instance, many system functions on Symbolics Lisp Machines that operate on lists have a :LOCALIZE option; when :LOCALIZE T is specified, the list is first modified and then copied to a new, CDR-coded block, with all the old cells replaced with forwarding pointers. The next time the garbage collector runs, all the forwarding pointers will be spliced out. Thus, at a cost of a temporary increase in memory usage, overall memory usage is generally reduced because more lists may be CDR-coded. There may also be some benefit in improved paging performance due to increased locality as well (putting a list into CDR-coded form makes all the "cells" contiguous). Nevertheless, modern Lisps tend to use lists much less frequently, with a much heavier reliance upon code, strings, and vectors (structures). ---------------------------------------------------------------- [2-12] What is garbage collection? Garbage Collection (GC) refers to the automatic storage allocation mechanisms present in many Lisps. There are several kinds of storage allocation algorithms, but most fall within two main classes: 1. Stop and Copy. Systems which copy active objects from "old" storage to "new" storage and then recycle the old storage. 2. Mark and Sweep. Systems which link together storage used by discarded objects. Generational scavenging garbage collection is a variation in which memory is allocated in layers, with tenured (long-lived) objects in the older layers. Rather than doing a full GC of all of memory every time more room is needed, only the last few layers are GCed during an ephemeral GC, taking much less time. Short-lived objects are quickly recycled, and full GCs are then much less frequent. It is most often used to improve the performance of stop and copy garbage collectors. It is possible to implement ephemeral GC in mark and sweep systems, just much more difficult. Stop and copy garbage collection provides simpler storage allocation, avoids fragmentation of memory (intermixing of free storage with used storage). Copying, however, consumes more of the address space, since up to half the space must be kept available for copying all the active objects. This makes stop and copy GC impractical for systems with a small address space or without virtual memory. Also, copying an object requires that you track down all the pointers to an object and update them to reflect the new address, while in a non-copying system you need only keep one pointer to an object, since its location will not change. It is also more difficult to explicitly return storage to free space in a copying system. Garbage collection is not part of the Common Lisp standard. Most Lisps provide a function ROOM which provides human-readable information about the state of storage usage. In many Lisps, (gc) invokes an ephemeral garbage collection, and (gc t) a full garbage collection. ---------------------------------------------------------------- [2-13] How do I save an executable image of my loaded Lisp system? How do I run a Unix command in my Lisp? How do I get the current directory name from within a Lisp program? There is no standard for dumping a Lisp image. Here are the commands from some lisp implementations: Lucid: DISKSAVE Symbolics: Save World [CP command] CMU CL: SAVE-LISP Franz Allegro: EXCL:DUMPLISP (documented) SAVE-IMAGE (undocumented) Medley: IL:SYSOUT or IL:MAKESYS MCL: SAVE-APPLICATION &key :toplevel-function :creator :excise-compiler :size :resources :init-file :clear-clos-caches KCL: (si:save-system "saved_kcl") There is no standard for running a Unix shell command from Lisp, especially since not all Lisps run on top of Unix. Here are the commands from some Lisp implementations: Allegro: EXCL:RUN-SHELL-COMMAND Lucid: RUN-PROGRAM (name &key input output error-output (wait t) arguments (if-input-does-not-exist :error) (if-output-exists :error) (if-error-output-exists :error)) KCL: SYSTEM For example, (system "ls -l"). There's no standard function for finding the current directory from within a Lisp program, since not all Lisp environments have the concept of a current directory. Here are the commands from some Lisp implementations: Lucid: working-directory (which is also SETFable) pwd and cd also work Allegro: current-directory (use excl:chdir to change it) CMU CL: default-directory Allegro also uses the variable *default-pathname-defaults* to resolve relative pathnames, maintaining it as the current working directory. So evaluating (truename "./") in Allegro (and on certain other systems) will return a pathname for the current directory. Likewise, in some VMS systems evaluating (truename "[]") will return a pathname for the current directory. ---------------------------------------------------------------- [2-14] I'm porting some code from a Symbolics Lisp machine to some other platform, and there are strange characters in the code. What do they mean? The Symbolics Zetalisp character set includes the following characters not present in other Lisps: ^] >= greater than or equal to ^\ <= less than or equal to ^Z != not equal to ^^ == equivalent to ^E not ^G pi ^L +/- plus/minus ^H lambda ^F epsilon ^W <--> left/right arrow ^X <-- left arrow ^Y --> right arrow Other special characters to look out for are the font-change characters, which are represented as a ^F followed by a digit or asterisk. A digit means to push font #N onto the stack; an asterisk means to pop the most recent font from the stack. You can clean up the code by replacing "\^F." with "". ---------------------------------------------------------------- [2-15] History: Where did Lisp come from? John McCarthy developed the basics behind Lisp during the 1956 Dartmouth Summer Research Project on Artificial Intelligence. He intended it as an algebraic LISt Processing (hence the name) language for artificial intelligence work. Early implementations included the IBM 704, the IBM 7090, the DEC PDP-1, the DEC PDP-6 and the DEC PDP-10. The PDP-6 and PDP-10 had 18-bit addresses and 36-bit words, allowing a CONS cell to be stored in one word, with single instructions to extract the CAR and CDR parts. The early PDP machines had a small address space, which limited the size of Lisp programs. Milestones in the development of Lisp: 1956 Dartmouth Summer Research Project on AI. 1960-65 Lisp1.5 is the primary dialect of Lisp. 1964- Development of BBNLisp at BBN. late 60s Lisp1.5 diverges into two main dialects: Interlisp (originally BBNLisp) and MacLisp. early 70s Development of special-purpose computers known as Lisp Machines, designed specificly to run Lisp programs. Xerox D-series Lisp Machines run Interlisp-D. Early MIT Lisp Machines run Lisp Machine Lisp (an extension of MacLisp). 1969 Anthony Hearn and Martin Griss define Standard Lisp to port REDUCE, a symbolic algebra system, to a variety of architectures. late 70s Macsyma group at MIT developed NIL (New Implementation of Lisp), a Lisp for the VAX. Stanford and Lawrence Livermore National Laboratory develop S-1 Lisp for the Mark IIA supercomputer. Franz Lisp (dialect of MacLisp) runs on stock-hardware Unix machines. Gerald J. Sussman and Guy L. Steele developed Scheme, a simple dialect of Lisp with lexical scoping and lexical closures, continuations as first-class objects, and a simplified syntax (i.e., only one binding per symbol). Advent of object-oriented programming concepts in Lisp. Flavors was developed at MIT for the Lisp machine, and LOOPS (Lisp Object Oriented Programming System) was developed at Xerox. early 80s Development of SPICE-Lisp at CMU, a dialect of MacLisp designed to run on the Scientific Personal Integrated Computing Environment (SPICE) workstation. 1980 First biannual ACM Lisp and Functional Programming Conf. 1981 PSL (Portable Standard Lisp) runs on a variety of platforms. 1981+ Lisp Machines from Xerox, LMI (Lisp Machines Inc) and Symbolics available commercially. April 1981 Grass roots definition of Common Lisp as a description of the common aspects of the family of languages (Lisp Machine Lisp, MacLisp, NIL, S-1 Lisp, Spice Lisp, Scheme). 1984 Publication of CLtL1. Common Lisp becomes a de facto standard. 1986 X3J13 forms to produce a draft for an ANSI Common Lisp standard. 1987 Lisp Pointers commences publication. 1990 Publication of CLtL2. Includes X3J13's additions of CLOS, conditions, pretty printing and iteration facilities. [Note: This summary is based primarily upon the History section of the draft ANSI specification. More detail and references can be obtained from that document when it becomes generally available.] ---------------------------------------------------------------- [2-16] How do I find the argument list of a function? There is no standard way to find the argument list of a function, since implementations are not required to save this information. However, many implementations do remember argument information, and usually have a function that returns the lambda list. Here are the commands from some Lisp implementations: Lucid: arglist Allegro: excl::arglist Symbolics: arglist CMU Common Lisp, new compiler: #+(and :CMU :new-compiler) (defun arglist (name) (let* ((function (symbol-function name)) (stype (system:%primitive get-vector-subtype function))) (when (eql stype system:%function-entry-subtype) (cadr (system:%primitive header-ref function system:%function-entry-type-slot))))) If you're interested in the number of required arguments you could use (defun required-arguments (name) (or (position-if #'(lambda (x) (member x lambda-list-keywords)) (arglist name)) (length (arglist name)))) ---------------------------------------------------------------- [2-17] How can I have two Lisp processes communicate via unix sockets? CLX uses Unix sockets to communicate with the X window server. Look at the following files from the CLX distribution for a good example of using Unix sockets from Lisp: defsystem.lisp Lucid, AKCL, IBCL, CMU. socket.c, sockcl.lisp AKCL, IBCL excldep.lisp Franz Allegro CL You will need the "socket.o" files which come with Lucid and Allegro. To obtain CLX, see the entry for CLX in the answer to question [2-2]. See the file lisp-sockets.text in the Lisp Utilities repository described in the answer to question [2-0]. ---------------------------------------------------------------- [2-18] When producing formatted output in Lisp, where should you put the newlines (e.g., before or after the line, FRESH-LINE vs TERPRI, ~& vs ~% in FORMAT)? Where possible, it is desirable to write functions that produce output as building blocks. In contrast with other languages, which either conservatively force a newline at various times or require the program to keep track of whether it needs to force a newline, the Lisp I/O system keeps track of whether the most recently printed character was a newline or not. The function FRESH-LINE outputs a newline only if the stream is not already at the beginning of a line. TERPRI forces a newline irrespective of the current state of the stream. These correspond to the ~& and ~% FORMAT directives, respectively. (If the Lisp I/O system can't determine whether it's physically at the beginning of a line, it assumes that a newline is needed, just in case.) Thus, if you want formatted output to be on a line of its own, start it with ~& and end it with ~%. (Some people will use a ~& also at the end, but this isn't necessary, since we know a priori that we're not at the beginning of a line. The only exception is when ~& follows a ~A, to prevent a double newline when the argument to the ~A is a formatted string with a newline at the end.) For example, the following routine prints the elements of a list, N elements per line, and then prints the total number of elements on a new line: (defun print-list (list &optional (elements-per-line 10)) (fresh-line) (loop for i upfrom 1 for element in list do (format t "~A ~:[~;~%~]" element (zerop (mod i elements-per-line)))) (format t "~&~D~%" (length list))) ---------------------------------------------------------------- ;;; *EOF* Path: think.com!zaphod.mps.ohio-state.edu!uwm.edu!ogicse!das-news.harvard.edu!cantaloupe.srv.cs.cmu.edu!crabapple.srv.cs.cmu.edu!mkant From: mkant+@cs.cmu.edu (Mark Kantrowitz) Newsgroups: comp.lang.lisp,news.answers Subject: FAQ: Lisp Frequently Asked Questions 3/5 [Monthly posting] Summary: Common Pitfalls Message-ID: Date: 14 Aug 92 00:39:48 GMT Article-I.D.: cs.lisp-faq-3.text_713752722 Expires: Sun, 27 Sep 1992 00:38:42 GMT Sender: news@cs.cmu.edu (Usenet News System) Reply-To: lisp-faq@think.com Followup-To: poster Organization: School of Computer Science, Carnegie Mellon Lines: 494 Approved: news-answers-request@MIT.Edu Supersedes: Nntp-Posting-Host: a.gp.cs.cmu.edu Xref: think.com comp.lang.lisp:8025 news.answers:2527 Archive-name: lisp-faq/part3 Last-Modified: Thu Aug 6 11:54:55 1992 by Mark Kantrowitz Version: 1.23 ;;; **************************************************************** ;;; Answers to Frequently Asked Questions about Lisp *************** ;;; **************************************************************** ;;; Written by Mark Kantrowitz and Barry Margolin ;;; lisp-faq-3.text -- 21696 bytes This post contains Part 3 of the Lisp FAQ. If you think of questions that are appropriate for this FAQ, or would like to improve an answer, please send email to us at lisp-faq@think.com. This section contains a list of common pitfalls. Pitfalls are aspects of Common Lisp which are non-obvious to new programmers and often seasoned programmers as well. Common Pitfalls (Part 3): [3-0] Why does (READ-FROM-STRING "foobar" :START 3) return FOOBAR instead of BAR? [3-1] Why can't it deduce from (READ-FROM-STRING "foobar" :START 3) that the intent is to specify the START keyword parameter rather than the EOF-ERROR-P and EOF-VALUE optional parameters? [3-2] Why can't I apply #'AND and #'OR? [3-3] I used a destructive function (e.g. DELETE, SORT), but it didn't seem to work. Why? [3-4] After I NREVERSE a list, it's only one element long. After I SORT a list, it's missing things. What happened? [3-5] Why does (READ-LINE) return "" immediately instead of waiting for me to type a line? [3-6] I typed a form to the read-eval-print loop, but nothing happened. Why? [3-7] DEFMACRO doesn't seem to work. When I compile my file, LISP warns me that my macros are undefined functions, or complains "Attempt to call which is defined as a macro. [3-8] Name conflict errors are driving me crazy! (EXPORT, packages) [3-9] Closures don't seem to work properly when referring to the iteration variable in DOLIST, DOTIMES and DO. [3-10] What is the difference between FUNCALL and APPLY? [3-11] Miscellaneous things to consider when debugging code. Search for [#] to get to question number # quickly. ---------------------------------------------------------------- [3-0] Why does (READ-FROM-STRING "foobar" :START 3) return FOOBAR instead of BAR? READ-FROM-STRING is one of the rare functions that takes both &OPTIONAL and &KEY arguments: READ-FROM-STRING string &OPTIONAL eof-error-p eof-value &KEY :start :end :preserve-whitespace When a function takes both types of arguments, all the optional arguments must be specified explicitly before any of the keyword arguments may be specified. In the example above, :START becomes the value of the optional EOF-ERROR-P parameter and 3 is the value of the optional EOF-VALUE parameter. ---------------------------------------------------------------- [3-1] Why can't it deduce from (READ-FROM-STRING "foobar" :START 3) that the intent is to specify the START keyword parameter rather than the EOF-ERROR-P and EOF-VALUE optional parameters? In Common Lisp, keyword symbols are first-class data objects. Therefore, they are perfectly valid values for optional parameters to functions. There are only four functions in Common Lisp that have both optional and keyword parameters (they are PARSE-NAMESTRING, READ-FROM-STRING, WRITE-LINE, and WRITE-STRING), so it's probably not worth adding a nonorthogonal kludge to the language just to make these functions slightly less confusing; unfortunately, it's also not worth an incompatible change to the language to redefine those functions to use only keyword arguments. ---------------------------------------------------------------- [3-2] Why can't I apply #'AND and #'OR? Here's the simple, but not necessarily satisfying, answer: AND and OR are macros, not functions; APPLY and FUNCALL can only be used to invoke functions, not macros and special operators. OK, so what's the *real* reason? The reason that AND and OR are macros rather than functions is because they implement control structure in addition to computing a boolean value. They evaluate their subforms sequentially from left/top to right/bottom, and stop evaluating subforms as soon as the result can be determined (in the case of AND, as soon as a subform returns NIL; in the case of OR, as soon as one returns non-NIL); this is referred to as "short circuiting" in computer language parlance. APPLY and FUNCALL, however, are ordinary functions; therefore, their arguments are evaluated automatically, before they are called. Thus, were APPLY able to be used with #'AND, the short-circuiting would be defeated. Perhaps you don't really care about the short-circuiting, and simply want the functional, boolean interpretation. While this may be a reasonable interpretation of trying to apply AND or OR, it doesn't generalize to other macros well, so there's no obvious way to have the Lisp system "do the right thing" when trying to apply macros. The only function associated with a macro is its expander function; this function accepts and returns and form, so it cannot be used to compute the value. The Common Lisp functions EVERY and SOME can be used to get the functionality you intend when trying to apply #'AND and #'OR. For instance, the erroneous form: (apply #'and *list*) can be translated to the correct form: (every #'identity *list*) ---------------------------------------------------------------- [3-3] I used a destructive function (e.g. DELETE, SORT), but it didn't seem to work. Why? I assume you mean that it didn't seem to modify the original list. There are several possible reasons for this. First, many destructive functions are not *required* to modify their input argument, merely *allowed* to; in some cases, the implementation may determine that it is more efficient to construct a new result than to modify the original (this may happen in Lisp systems that use "CDR coding", where RPLACD may have to turn a CDR-NEXT or CDR-NIL cell into a CDR-NORMAL cell), or the implementor may simply not have gotten around to implementing the destructive version in a truly destructive manner. Another possibility is that the nature of the change that was made involves removing elements from the front of a list; in this case, the function can simply return the appropriate tail of the list, without actually modifying the list. And example of this is: (setq *a* (list 3 2 1)) (delete 3 *a*) => (2 1) *a* => (3 2 1) Similarly, when one sorts a list, SORT may destructively rearrange the pointers (cons cells) that make up the list. SORT then returns the cons cell that now heads the list; the original cons cell could be anywhere in the list. The value of any variable that contained the original head of the list hasn't changed, but the contents of that cons cell have changed because SORT is a destructive function: (setq *a* (list 2 1 3)) (sort *a* #'<) => (1 2 3) *a* => (2 3) In both cases, the remedy is the same: store the result of the function back into the place whence the original value came, e.g. (setq *a* (delete 3 *a*)) *a* => (2 1) Why don't the destructive functions do this automatically? Recall that they are just ordinary functions, and all Lisp functions are called by value. Therefore, these functions do not know where the lists they are given came from; they are simply passed the cons cell that represents the head of the list. Their only obligation is to return the new cons cell that represents the head of the list. One thing to be careful about when doing this is that the original list might be referenced from multiple places, and all of these places may need to be updated. For instance: (setq *a* (list 3 2 1)) (setq *b* *a*) (setq *a* (delete 3 *a*)) *a* => (2 1) *b* => (3 2 1) ; *B* doesn't "see" the change (setq *a* (delete 1 *a*)) *a* => (2) *b* => (3 2) ; *B* sees the change this time, though One may argue that destructive functions could do what you expect by rearranging the CARs of the list, shifting things up if the first element is being deleted, as they are likely to do if the argument is a vector rather than a list. In many cases they could do this, although it would clearly be slower. However, there is one case where this is not possible: when the argument or value is NIL, and the value or argument, respectively, is not. It's not possible to transform the object referenced from the original cell from one data type to another, so the result must be stored back. Here are some examples: (setq *a* (list 3 2 1)) (delete-if #'numberp *a) => NIL *a* => (3 2 1) (setq *a* nil *b* '(1 2 3)) (nconc *a* *b*) => (1 2 3) *a* => NIL The names of most destructure functions (except for sort, delete, rplaca, rplacd, and setf of accessor functions) have the prefix N. In summary, the two common problems to watch out for when using destructive functions are: 1. Forgetting to store the result back. Even though the list is modified in place, it is still necessary to store the result of the function back into the original location, e.g., (setq foo (delete 'x foo)) If the original list was stored in multiple places, you may need to store it back in all of them, e.g. (setq bar foo) ... (setq foo (delete 'x foo)) (setq bar foo) 2. Sharing structure that gets modified. If it is important to preserve the shared structure, then you should either use a nondestructive operation or copy the structure first using COPY-LIST or COPY-TREE. (setq bar (cdr foo)) ... (setq foo (sort foo #'<)) ;;; now it's not safe to use BAR Note that even nondestructive functions, such as REMOVE, and UNION, can return a result which shares structure with an argument. Nondestructive functions don't necessarily copy their arguments; they just don't modify them. ---------------------------------------------------------------- [3-4] After I NREVERSE a list, it's only one element long. After I SORT a list, it's missing things. What happened? These are particular cases of the previous question. Many NREVERSE and SORT implementations operate by rechaining all the CDR links in the list's backbone, rather than by replacing the CARs. In the case of NREVERSE, this means that the cons cell that was originally first in the list becomes the last one. As in the last question, the solution is to store the result back into the original location. ---------------------------------------------------------------- [3-5] Why does (READ-LINE) return "" immediately instead of waiting for me to type a line? Many Lisp implementations on line-buffered systems do not discard the newline that the user must type after the last right parenthesis in order for the line to be transmitted from the OS to Lisp. Lisp's READ function returns immediately after seeing the matching ")" in the stream. When READLINE is called, it sees the next character in the stream, which is a newline, so it returns an empty line. If you were to type "(read-line)This is a test" the result would be "This is a test". The simplest solution is to use (PROGN (CLEAR-INPUT) (READ-LINE)). This discards the buffered newline before reading the input. However, it would also discard any other buffered input, as in the "This is a test" example above; some implementation also flush the OS's input buffers, so typeahead might be thrown away. ---------------------------------------------------------------- [3-6] I typed a form to the read-eval-print loop, but nothing happened. Why? There's not much to go on here, but a common reason is that you haven't actually typed a complete form. You may have typed a doublequote, vertical bar, "#|" comment beginning, or left parenthesis that you never matched with another doublequote, vertical bar, "|#", or right parenthesis, respectively. Try typing a few right parentheses followed by Return. ---------------------------------------------------------------- [3-7] DEFMACRO doesn't seem to work. When I compile my file, LISP warns me that my macros are undefined functions, or complains "Attempt to call which is defined as a macro. When you evaluate a DEFMACRO form or proclaim a function INLINE, it doesn't go back and update code that was compiled under the old definition. When redefining a macro, be sure to recompile any functions that use the macro. Also be sure that the macros used in a file are defined before any forms in the same file that use them. Certain forms, including LOAD, SET-MACRO-CHARACTER, and REQUIRE, are not normally evaluated at compile time. Common Lisp requires that macros defined in a file be used when compiling later forms in the file. If a Lisp doesn't follow the standard, it may be necessary to wrap an EVAL-WHEN form around the macro definition. Most often the "macro was previously called as a function" problem occurs when files were compiled/loaded in the wrong order. For example, developers may add the definition to one file, but use it in a file which is compiled/loaded before the definition. To work around this problem, one can either fix the modularization of the system, or manually recompile the files containing the forward references to macros. Also, if your macro calls functions at macroexpand time, those functions may need to be in an EVAL-WHEN. For example, (defun some-function (x) x) (defmacro some-macro (y) (let ((z (some-function y))) `(print ',z))) If the macros are defined in a file you require, make sure your require or load statement is in an appropriate EVAL-WHEN. Many people avoid all this nonsense by making sure to load all their files before compiling them, or use a system facility (or just a script file) that loads each file before compiling the next file in the system. ---------------------------------------------------------------- [3-8] Name conflict errors are driving me crazy! (EXPORT, packages) If a package tries to export a symbol that's already defined, it will report an error. You probably tried to use a function only to discover that you'd forgotten to load its file. The failed attempt at using the function caused its symbol to be interned. So now, when you try to load the file, you get a conflict. Unfortunately, understanding and correcting the code which caused the export problem doesn't make those nasty error messages go away. That symbol is still interned where it shouldn't be. Use unintern to remove the symbol from a package before reloading the file. Also, when giving arguments to REQUIRE or package functions, use strings or keywords, not symbols: (find-package "FOO"), (find-package :foo). A sometimes useful technique is to rename (or delete) a package that is "too messed up". Then you can reload the relevant files into a "clean" package. ---------------------------------------------------------------- [3-9] Closures don't seem to work properly when referring to the iteration variable in DOLIST, DOTIMES and DO. DOTIMES, DOLIST, and DO all use assignment instead of binding to update the value of the iteration variables. So something like (dotimes (n 10) (push #'(lambda () (incf n)) *counters*)) will produce 10 closures over the same value of the variable N. ---------------------------------------------------------------- [3-10] What is the difference between FUNCALL and APPLY? FUNCALL is useful when the programmer knows the length of the argument list, but the function to call is either computed or provided as a parameter. For instance, a simple implementation of MEMBER-IF (with none of the fancy options) could be written as: (defun member-if (predicate list) (do ((tail list (cdr tail))) ((null tail)) (when (funcall predicate (car tail)) (return-from member-if tail)))) The programmer is invoking a caller-supplied function with a known argument list. APPLY is needed when the argument list itself is supplied or computed. Its last argument must be a list, and the elements of this list become individual arguments to the function. This frequently occurs when a function takes keyword options that will be passed on to some other function, perhaps with application-specific defaults inserted. For instance: (defun open-for-output (pathname &rest open-options) (apply #'open pathname :direction :output open-options)) FUNCALL could actually have been defined using APPLY: (defun funcall (function &rest arguments) (apply function arguments)) ---------------------------------------------------------------- [3-11] Miscellaneous things to consider when debugging code. This question lists a variety of problems to watch out for when debugging code. This is sort of a catch-all question for problems too small to merit a question of their own. See also question [1-2] for some other common problems. Functions: * (flet ((f ...)) (eq #'f #'f)) can return false. * The function LIST-LENGTH is not a faster, list-specific version of the sequence function LENGTH. It is list-specific, but it's slower than LENGTH because it can handle circular lists. * Some destructive functions that you think would modify CDRs might modify CARs instead. (E.g., NREVERSE.) * READ-FROM-STRING has some optional arguments before the keyword parameters. If you want to supply some keyword arguments, you have to give all of the optional ones too. * If you use the function READ-FROM-STRING, you should probably bind *READ-EVAL* to NIL. Otherwise an unscrupulous user could cause a lot of damage by entering #.(shell "cd; rm -R *") at a prompt. Methods: * PRINT-OBJECT methods can make good code look buggy. If there is a problem with the PRINT-OBJECT methods for one of your classes, it could make it seem as though there were a problem with the object. It can be very annoying to go chasing through your code looking for the cause of the wrong value, when the culprit is just a bad PRINT-OBJECT method. Initialization: * Don't count on array elements being initialized to NIL, if you don't specify an :initial-element argument to MAKE-ARRAY. For example, (make-array 10) => #(0 0 0 0 0 0 0 0 0 0) Iteration vs closures: * DO and DO* update the iteration variables by assignment; DOLIST and DOTIMES are allowed to use assignment (rather than a new binding). (All CLtL says of DOLIST and DOTIMES is that the variable "is bound" which has been taken as _not_ implying that there will be separate bindings for each iteration.) Consequently, if you make closures over an iteration variable in separate iterations they may nonetheless be closures over the same variable and hence will all refer to the same value -- whatever value the variable was given last. Eg, (let ((fns '())) (do ((x '(1 2) (cdr x))) ((null x)) (push #'(lambda () x) fns)) (mapcar #'funcall (reverse fns))) returns (nil nil), not (1 2), not even (2 2). Defining Variables and Constants: * (DEFVAR var init) assigns to the variable only if it does not already have a value. So if you edit a DEFVAR in a file and reload the file only to find that the value has not changed, this is the reason. (Use DEFPARAMETER if you want the value to change upon reloading.) * DEFCONSTANT has several potentially unexpected properties: - Once a name has been declared constant, it cannot be used a the name of a local variable (lexical or special) or function parameter. Really. See page 87 of CLtL II. - A DEFCONSTANT cannot be re-evaluated (eg, by reloading the file in which it appears) unless the new value is EQL to the old one. Strictly speaking, even that may not be allowed. (DEFCONSTANT is "like DEFPARAMETER" and hence does an assignment, which is not allowed if the name has already been declared constant by DEFCONSTANT.) Note that this makes it difficult to use anything other than numbers, symbols, and characters as constants. - When compiling (DEFCONSTANT name form) in a file, the form may be evaluated at compile-time, load-time, or both. (You might think it would be evaluated at compile-time and the _value_ used to obtain the object at load-time, but it doesn't have to work that way.) Declarations: * You often have to declare the result type to get the most efficient arithmetic. Eg, (the fixnum (+ (the fixnum e1) (the fixnum e2))) rather than (+ (the fixnum e1) (the fixnum e2)) * Declaring the iteration variable of a DOTIMES to have type FIXNUM does not guarantee that fixnum arithmetic will be used. That is, implementations that use fixnum-specific arithmetic in the presence of appropriate declaration may not think _this_ declaration is sufficient. It may help to declare that the limit is also a fixnum, or you may have to write out the loop as a DO and add appropriate declarations for each operation involved. Miscellaneous: * Be careful of circular lists and shared list structure. * Watch out for macro redefinitions. * If you use (SETF SYMBOL-FUNCTION) to change the definition of built-in Lisp functions, be aware that this may not work correctly (i.e., as desired) in compiled code in all Lisps. In some Lisps, the compiler treats certain symbols in the LISP package specially, ignoring the function definition. * A NOTINLINE may be needed if you want SETF of SYMBOL-FUNCTION to affect calls within a file. (See CLtL2, page 686.) ---------------------------------------------------------------- ;;; *EOF* Path: think.com!zaphod.mps.ohio-state.edu!uwm.edu!ogicse!das-news.harvard.edu!cantaloupe.srv.cs.cmu.edu!crabapple.srv.cs.cmu.edu!mkant From: mkant+@cs.cmu.edu (Mark Kantrowitz) Newsgroups: comp.lang.lisp,comp.lang.scheme,news.answers Subject: FAQ: Lisp Implementations and Mailing Lists 4/5 [Monthly posting] Summary: Questions about Lisp/Scheme Implementations and Mailing Lists Message-ID: Date: 14 Aug 92 00:40:33 GMT Article-I.D.: cs.lisp-faq-4.text_713752811 Expires: Sun, 27 Sep 1992 00:40:11 GMT Sender: news@cs.cmu.edu (Usenet News System) Reply-To: lisp-faq@think.com Followup-To: poster Organization: School of Computer Science, Carnegie Mellon Lines: 709 Approved: news-answers-request@MIT.Edu Supersedes: Nntp-Posting-Host: a.gp.cs.cmu.edu Xref: think.com comp.lang.lisp:8026 comp.lang.scheme:5047 news.answers:2528 Archive-name: lisp-faq/part4 Last-Modified: Thu Aug 6 11:54:55 1992 by Mark Kantrowitz Version: 1.23 ;;; **************************************************************** ;;; Answers to Frequently Asked Questions about Lisp *************** ;;; **************************************************************** ;;; Written by Mark Kantrowitz and Barry Margolin ;;; lisp-faq-4.text -- 38668 bytes This post contains Part 4 of the Lisp FAQ. It is cross-posted to the newsgroup comp.lang.scheme because it contains material of interest to Scheme people. The other parts of the Lisp FAQ are posted only to the newsgroups comp.lang.lisp and news.answers. If you think of questions that are appropriate for this FAQ, or would like to improve an answer, please send email to us at lisp-faq@think.com. Lisp/Scheme Implementations and Mailing Lists (Part 4): [4-0] Where can I get/buy Lisp and Scheme for the ... architecture? [4-1] Where can I get an implementation of Prolog in Lisp? [4-2] What is Dylan? [4-3] What Lisp-related discussion groups and mailing lists exist? Search for [#] to get to question number # quickly. ---------------------------------------------------------------- [4-0] Where can I get/buy Lisp and Scheme for the ... architecture? There are many implementations of Lisp and Scheme interpreters and compilers, about half of which are available free and the rest are available commercially. Repositories of Lisp/Scheme source code are described in the answer to question [2-0]. Free Lisp implementations: Kyoto Common Lisp (KCL) is free, but requires a license. Conforms to CLtL1. KCL was written by T. Yuasa and M. Hagiya at Kyoto University. Austin Kyoto Common Lisp (AKCL) is a collection of ports, bug fixes and improvements to KCL by Bill Schelter ( or ). {A}KCL generates C code which it compiles with the local C compiler. Both are available by anonymous ftp from rascal.ics.utexas.edu [128.83.138.20], cli.com [192.31.85.1], or [133.11.11.11] (a machine in Japan) in the directory /pub. KCL is in the file kcl.tar, and AKCL is in the file akcl-xxx.tar.Z (take the highest value of xxx). To obtain KCL, one must first sign and mail a copy of the license agreement to: Special Interest Group in LISP, c/o Taiichi Yuasa, Department of Computer Science, Toyohashi University of Technology, Toyohashi 441, JAPAN. Runs on Sparc, IBM RT, RS/6000, DecStation 3100, hp300, hp800, Macintosh II (under AUX), mp386, IBM PS2, Silicon Graphics 4d, Sun3, Sun4, Sequent Symmetry, IBM 370, NeXT and Vax. A port to DOS is in beta test as math.utexas.edu:pub/beta2.zip. Commercial versions of {A}KCL are available from Austin Code Works, 1110 Leafwood Lane, Austin, TX 78750-3409, Tel. 512-258-0785, Fax 512-258-1342, including a CLOS for AKCL. See also Ibuki, below. XLISP is free, and runs on the IBM PC (MSDOS), Amiga (AmigaDOS), Atari ST (TOS), Apple Macintosh, and Unix. It should run on anything with a C compiler. It was written by David Michael Betz, 127 Taylor Road, Peterborough, NH 03458. The reference manual was written by Tim Mikkelsen. Version 2.0 is available by anonymous ftp from cs.orst.edu:/pub/xlisp/ [128.193.32.1] or sumex-aim.stanford.edu:info-mac/lang/ Version 2.1 is the same as XLISP 2.0, but modified to bring it closer to Common Lisp and with several bugs fixed. It can be obtained by anonymous ftp from glia.biostr.washington.edu 128.95.10.115 bikini.cis.ufl.edu 128.227.224.1 in the file xlisp21c.zip (soon xlisp21d.zip) and comes with IBM/PC executables. For obtaining a copy through US mail, send email to Tom Almy, toma@sail.labs.tek.com. CMU Common Lisp is free, and runs on Sparcs (Mach and SunOs), DecStation 3100 (Mach), IBM RT (Mach) and requires 16mb RAM, 25mb disk. It includes an incremental compiler, Hemlock emacs-style editor, source-code level debugger, code profiler and is mostly X3J13 compatible, including the new loop macro. It is available by anonymous ftp from any CMU CS machine, such as ftp.cs.cmu.edu [128.2.206.173], in the directory /afs/cs.cmu.edu/project/clisp/release. Login with username "anonymous" and "userid@host" (your email address) as password. Due to security restrictions on anonymous ftps (some of the superior directories on the path are protected against outside access), it is important to "cd" to the source directory with a single command. Don't forget to put the ftp into binary mode before using "get" to obtain the compressed/tarred files. The binary releases are contained in files of the form -_.tar.Z Other files in this directory of possible interest are {15e,16c}-source.tar.Z, which contains all the ".lisp" source files used to build version 15e and 16c. Use "dir" or "ls" to see what is available. Bug reports should be sent to cmucl-bugs@cs.cmu.edu. PC LISP is a Lisp interpreter for IBM PCs (MSDOS) available from any site that archives the group comp.binaries.ibm.pc, such as ix1.cc.utexas.edu:/microlib/pc/languages/pc-lisp/ps-lisp.arc wuarchive.wustl.edu:/mirrors/msdos/lisp/pclisp30.zip PC-LISP is a Franz LISP dialect and is by no means Common LISP compatible. It is also available directly from the author by sending 2 blank UNFORMATTED 360K 48TPI IBM PC diskettes, a mailer and postage to: Peter Ashwood-Smith, 8 Du Muguet, Hull, Quebec, CANADA, J9A-2L8; phone 819-595-9032 (home). Free Scheme implementations: Many free Scheme implementations are available from altdorf.ai.mit.edu [18.43.0.246]. See also the Scheme Repository described below. The Scheme Repository contains a Scheme bibliography, copies of the R4RS report, sample Scheme code for a variety of purposes, several utilities, and some implementations. The repository is maintained by Ozan S. Yigit, scheme@nexus.yorku.ca. The repository is accessible by anonymous ftp at nexus.yorku.ca [130.63.9.66] in the directory pub/scheme/. PC-Scheme, free by anonymous ftp from altdorf.ai.mit.edu in the directory /archive/pc-scheme/. Written by Texas Instruments. Runs on MS-DOS 286/386 IBM PCs and compatibles. Includes an optimizing compiler, an emacs-like editor, inspector, debugger, performance testing, foreign function interface, window system and an object-oriented subsystem. Conforms to the Revised^4 Report on Scheme. Also supports the dialect used in SICP. The official commercialized implementation costs $95 and includes a reference manual and user's guide. Write to: Texas Instruments, 12501 Research Boulevard, MS 2151, Austin, TX 78759 and order TI Part number #2537900-0001, or call 1-800-TI-PARTS and order it using your Visa or Mastercard. [NOTE: Ibuki announced on July 13, 1992, that it has purchased the rights to PC Scheme from TI and intends to make it also available on 486 PCs and under Windows 3.1. For more information, contact IBUKI, PO Box 1627, Los Altos, CA 94022, phone (415) 961-4996, fax (415) 961-8016, email rww@ibuki.com.] MIT Scheme (aka C-Scheme), free by anonymous ftp from altdorf.ai.mit.edu in the directory scheme-7.1. The compiler is currently ported to four architectures: MC68020/30/40, HP Precision Architecture, MIPS, and VAX. The interpreter will soon be available for any Unix-based machine. Includes a reference manual and user's manual, as well as a copy of the Revised^4 Report on Scheme. Send bug reports to bug-cscheme@zurich.ai.mit.edu. | On the NeXT, MIT Scheme is available as part of the Schematik package, which provides an editor/front-end user interface, graphics, and "robotics" support for Lego and the like. Schematik is free and is available for anonymous ftp from ftp.gac.edu in the pub/next/scheme directory. SCM, free by anonymous ftp from altdorf.ai.mit.edu:archive/scm or nexus.yorku.ca:p