home *** CD-ROM | disk | FTP | other *** search
- Path: bloom-beacon.mit.edu!uhog.mit.edu!nntp.club.cc.cmu.edu!cantaloupe.srv.cs.cmu.edu!mkant
- From: mkant+@cs.cmu.edu (Mark Kantrowitz)
- Newsgroups: comp.lang.lisp,news.answers,comp.answers
- Subject: FAQ: Lisp Frequently Asked Questions 2/7 [Monthly posting]
- Supersedes: <LISP_2_782031621@CS.CMU.EDU>
- Followup-To: poster
- Date: 13 Nov 1994 08:00:57 GMT
- Organization: Carnegie-Mellon University, School of Computer Science
- Lines: 975
- Approved: news-answers-request@MIT.Edu
- Distribution: world
- Expires: 25 Dec 1994 08:00:25 GMT
- Message-ID: <LISP_2_784713625@CS.CMU.EDU>
- References: <LISP_1_784713625@CS.CMU.EDU>
- Reply-To: ai+lisp-faq@cs.cmu.edu
- NNTP-Posting-Host: glinda.oz.cs.cmu.edu
- Summary: Frequently asked questions about Lisp -- General Questions
- Xref: bloom-beacon.mit.edu comp.lang.lisp:7452 news.answers:29281 comp.answers:8316
-
- Archive-name: lisp-faq/part2
- Last-Modified: Thu Oct 20 22:09:18 1994 by Mark Kantrowitz
- Version: 1.51
- Maintainer: Mark Kantrowitz and Barry Margolin <ai+lisp-faq@cs.cmu.edu>
- URL: http://www.cs.cmu.edu:8001/Web/Groups/AI/html/faqs/lang/lisp/top.html
- Size: 48722 bytes, 983 lines
-
- ;;; ****************************************************************
- ;;; Answers to Frequently Asked Questions about Lisp ***************
- ;;; ****************************************************************
- ;;; Written by Mark Kantrowitz and Barry Margolin
- ;;; lisp_2.faq
-
- 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 ai+lisp-faq@cs.cmu.edu.
-
- Topics Covered (Part 2):
-
- [2-1] Is there a GNU-Emacs interface to Lisp?
- [2-2] When should I use a hash table instead of an association list?
- [2-3] What is the equivalent of EXPLODE and IMPLODE in Common Lisp?
- [2-4] Is Lisp inherently slower than more conventional languages such as C?
- [2-5] Why does Common Lisp have "#'"?
- [2-6] How do I call non-Lisp functions from Lisp?
- [2-7] Can I call Lisp functions from other languages?
- [2-8] I want to call a function in a package that might not exist at
- compile time. How do I do this?
- [2-9] What is CDR-coding?
- [2-10] What is garbage collection?
- [2-11] 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 exit Lisp?
- [2-12] 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-13] History: Where did Lisp come from?
- [2-14] How do I find the argument list of a function?
- How do I get the function name from a function object?
- [2-15] How can I have two Lisp processes communicate via unix sockets?
- [2-16] How can I create a stream that acts like UNIX's /dev/null
- (i.e., gobbles any output and immediately signals EOF on
- input operations)?
- [2-17] Read-time conditionalization of code (#+ #- and *features*)
- [2-18] What reader macro characters are used in major Lisp systems?
- [2-19] How do I determine if a file is a directory or not?
- How do I get the current directory name from within a Lisp
- program? Is there any way to create a directory?
- [2-20] What is a "Lisp Machine" (LISPM)?
- [2-21] How do I tell if a symbol names a function and not a macro?
-
- Search for \[#\] to get to question number # quickly.
-
- ----------------------------------------------------------------
- Subject: [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 <ccm+@cs.cmu.edu> and now maintained by Marco Antoniotti
- <marcoxa@cs.nyu.edu> and Rick Busdiecker <rfb@lehman.com>. It is
- available by anonymous ftp from
- h.gp.cs.cmu.edu:/usr/rfb/ilisp/ [128.2.254.156]
- as the file ilisp-5.6.tar.gz. It is also available in the CMU AI
- Repository in
- ftp.cs.cmu.edu:/user/ai/lang/lisp/util/emacs/ilisp/
- If you want to be on the ilisp mailing list, to hear about new
- releases and patches, send mail to ilisp-request@lehman.com. Please
- send any comments, code, or bug reports to ilisp@lehman.com.
-
- Franz Inc.'s GNU-Emacs/Lisp interface includes an online Common Lisp
- manual. (The manual is available by license from Franz Inc. Contact
- info@franz.com for more information.) The Emacs-Lisp interface
- (without the online Common Lisp reference manual and some
- Allegro-specific code) is available free from
- ftp.uu.net:/vendor/franz/emacs/eli-2.0.11.tar.gz
- and takes advantage of GNU-Emacs 19.X's newest features, including
- support for mouse input, pulldown menus, and multifont text. The
- interface also supports Epoch 3.2 and 4.2, and LEmacs 19.6 and 19.8.
- For discussion of the Franz lisp-emacs interface, join the
- allegro-cl-request@cs.berkeley.edu mailing list.
- (See also [1-2] for a hardcopy version of the Common Lisp reference manual.)
-
- 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.
-
- GNU-Emacs itself is available by anonymous ftp from prep.ai.mit.edu.
-
- Edebug, a debugger for Emacs Lisp, and some utilities for Common Lisp
- debugging (Dave Gillespie's version of cl.el) are available by
- anonymous ftp from
- a.cs.uiuc.edu:/pub/edebug/
- To join the Edebug mailing list edebug@cs.uiuc.edu send mail to
- edebug-request@cs.uiuc.edu. For more information, write to Daniel
- LaLiberte <liberte@cs.uiuc.edu>.
-
- ----------------------------------------------------------------
- Subject: [2-2] When should I use a hash table instead of an association list?
-
- Both association lists (alists) and hash tables may be used to
- represent tabular data. Hash tables have an O(1) running time and
- alists an O(n) running time, so hash tables are ultimately more
- efficient than alists. However, if the alists are small, they can be
- more efficient than hash tables, which have a large initial overhead.
-
- Alists can sometimes be more efficient if the keys are sorted
- according to frequency, with the most heavily accessed keys appearing
- at the front of the list. But one doesn't always know this kind of
- information, and even then the frequency distribution may be flat.
-
- In Allegro CL 4.1 [SPARC; R1], the rule of thumb is that for less than
- 24 elements, linear search using alists beats hashing. In Lucid CL
- 4.0.1 HP 9000/700, the break-even point is at 10 elements. The
- break-even points vary in other lisps from as low as 4 elements to as
- high as 100 elements. So if you're using alists in your code, using
- hash tables instead may speed up your program.
-
- A potential problem may occur, however, when the keys of an EQ or EQL
- hash table are Lisp objects such as conses or arrays (or other objects
- that are identified by their addresses). In most implementations, such
- tables must be re-hashed after garbage collection. If your application
- causes frequent GCs, this can adversely affect the performance of hash
- table lookup. Since EQL-hashing and =-hashing of fixnums generally
- don't require rehashing after GC, one way of avoiding this problem is
- to include a unique identifier in each key object and hash on that
- instead. Another solution is to use an EQUAL hash table if the keys
- are conses or an EQUALP hash table if the keys are arrays or other
- (non-circular!) structures.
-
- ----------------------------------------------------------------
- Subject: [2-3] 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.
-
- ----------------------------------------------------------------
- Subject: [2-4] Is Lisp inherently slower than more conventional languages
- such as C?
-
- This is a tough question to answer, as you probably 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 denser (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. A more
- recent test found that numeric code compiled with optimizations using
- CMU CL is within the same ballpark as highly optimized Fortran code.
- For unoptimized Fortran code, CMU CL was about 4 times faster.
- Even the speed of numeric code generated by other Lisp compilers
- (AKCL, Allegro, Lucid) was well within an order of magnitude of good
- Fortran and C compilers (although slower than CMU CL). Inspection of
- the emitted C code from AKCL doesn't reveal many obvious sources of
- inefficiency. (Since AKCL compiles Lisp into C, there are many cases
- where KCL code is as fast as hand-written C code.)
-
- See the paper peoplesparc.berkeley.edu:/pub/papers/fastlisp.ps.Z
- for a discussion of the speed of Lisp vis a vis Fortran or C.
-
- 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.
-
- ----------------------------------------------------------------
- Subject: [2-5] 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.
-
- ----------------------------------------------------------------
- Subject: [2-6] 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, one 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.
-
- ----------------------------------------------------------------
- Subject: [2-7] 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. Note that in such foreign function
- interfaces Lisp is often left "in control" of things like memory
- allocation, I/O channels, and startup code (this is a major nuisance
- for lots of people).
-
- ----------------------------------------------------------------
-
- Subject: [2-8] 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) ...).
-
- ----------------------------------------------------------------
- Subject: [2-9] 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).
-
- ----------------------------------------------------------------
- Subject: [2-10] 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 (aka emphemeral GC) 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.
-
- ----------------------------------------------------------------
- Subject: [2-11] 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 exit Lisp?
-
- 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 <pathname>
- &key :toplevel-function :creator :excise-compiler
- :size :resources :init-file :clear-clos-caches
- KCL: (si:save-system "saved_kcl")
- LispWorks: LW:SAVE-IMAGE
- Be sure to garbage collect before dumping the image. You may need to
- experiment with the kind of garbage collection for large images, and
- may find better results if you build the image in stages.
-
- 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").
- You can also try RUN-PROCESS and EXCLP, but they
- don't work with all versions of KCL.
- CMU CL: RUN-PROGRAM (program args
- &key (env *environment-list*) (wait t) pty input
- if-input-does-not-exist output
- (if-output-exists :error) (error :output)
- (if-error-exists :error) status-hook before-execve)
- LispWorks: FOREIGN:CALL-SYSTEM-SHOWING-OUTPUT
-
- To toggle source file recording and cross-reference annotations, use
- Allegro: excl:*record-source-file-info*
- excl:*load-source-file-info*
- excl:*record-xref-info*
- excl:*load-xref-info*
- LispWorks: (toggle-source-debugging nil)
-
- Memory management:
- CMU CL: (bytes-consed-between-gcs) [this is setfable]
- Lucid: (change-memory-management
- &key growth-limit expand expand-reserved)
- Allegro: *tenured-bytes-limit*
- LispWorks: LW:GET-GC-PARAMETERS
- (use LW:SET-GC-PARAMETERS to change them)
-
- Exiting/Quitting:
- CLISP: EXIT
- Allegro: EXIT (&optional excl::code &rest excl::args
- &key excl::no-unwind excl::quiet)
- LispWorks:
- Lucid: QUIT (&optional (lucid::status 0))
- CMU CL: QUIT (&optional recklessly-p)
-
- ----------------------------------------------------------------
- Subject: [2-12] 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 (^ means control):
- ^] >= 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
- ^A down arrow
- ^K up arrow
- ^D up caret
- ^_ down caret
- ^T forall
- ^U there exists
- ^B alpha
- ^C beta
- ^I gamma
- ^J delta
- ^O partial delta
- ^N infinity
- ^M circle +
- ^V circle x
-
- 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 "". In format statements, ^P and ^Q are used to delimit text to
- be printed in a particular character style.
-
- ----------------------------------------------------------------
- Subject: [2-13] 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 Steele publishes CLtL2 which offers a snapshot of
- work in progress by X3J13. (Unlike CLtL1, CLtL2
- was NOT an output of the standards process and was
- not intended to become a de facto standard. Read
- the Second Edition Preface for further explanation
- of this important issue.) Includes CLOS,
- conditions, pretty printing and iteration facilities.
-
- 1992 X3J13 creates a draft proposed American National
- Standard for Common Lisp. This document is the
- first official successor to CLtL1.
-
- [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. See [4-12] for information on obtaining a copy.]
-
- Gabriel and Steele's "The Evolution of Lisp", which appeared in the
- 1993 ACM History of Programming Languages conference, is available by
- anonymous ftp from
- ftp.cs.umbc.edu:/pub/Memoization/Misc/ [130.85.100.53]
- as Evolution-of-Lisp.ps.Z.
-
- ----------------------------------------------------------------
- Subject: [2-14] How do I find the argument list of a function?
- How do I get the function name from a function object?
-
- 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
- LispWorks: lw:function-lambda-list
-
- 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)))))
-
- The draft ANSI standard does include FUNCTION-LAMBDA-EXPRESSION and
- FUNCTION-KEYWORDS, which can be used to create an ARGLIST function.
-
- 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))))
-
- To extract the function name from the function object, as in
- (function-name #'car) ==> 'car
- use the following vendor-dependent functions:
-
- Symbolics: (si::compiled-function-name <fn>)
- (unless (si:lexical-closure-p <fn>) ...)
- Lucid: (sys::procedure-ref <fn> SYS:PROCEDURE-SYMBOL)
- (when (sys:procedurep <fn>) ..)
- Allegro: (xref::object-to-function-name <fn>)
- CMU CL: (kernel:%function-header-name <fn>)
- AKCL: (system::compiled-function-name <fn>)
- MCL: (ccl::function-name <fn>)
- Harlequin: (system::function-name <fn>)
-
- If a vendor-dependent function does not exist, the following
- (inefficient) code maps over all symbols looking for one whose
- function-cell matches the function object.
-
- (defun function-name (fobject)
- (do-all-symbols (fsymbol)
- (when (and (fboundp fsymbol)
- (eq (symbol-function fsymbol) fobject))
- (return fsymbol))))
-
- If a vendor supports FUNCTION-LAMBDA-EXPRESSION, the third value is
- the name of the function, if available.
-
- ----------------------------------------------------------------
- Subject: [2-15] 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 [7-1].
-
- See the file sockets.tar.gz in the Lisp Utilities repository
- described in the answer to question [6-1].
-
- ----------------------------------------------------------------
- Subject: [2-16] How can I create a stream that acts like UNIX's /dev/null
- (i.e., gobbles any output and immediately signals EOF on
- input operations)?
-
- (defparameter *dev-null*
- #-lispm
- (make-two-way-stream (make-concatenated-stream) (make-broadcast-stream))
- ;; Since Lisp Machines have a built-in /dev/null which handles
- ;; additional, non-standard operations, we'll use that instead.
- #+lispm #'system:null-stream)
-
- ----------------------------------------------------------------
- Subject: [2-17] Read-time conditionalization of code (#+ #- and *features*)
-
- The #+ and #- syntax provides for the read-time conditionalization of
- lisp code, depending on the presence or absence of keywords on the
- *features* list. The nascent Common Lisp standard does not specify
- what keywords an implementation must have on its features list.
- Nevertheless, most implementations have features that allow one to
- distinguish the implementation from other implementations. This allows
- one to write implementation-dependent code that is run only in the
- relevant implementations.
-
- Here is a list of the features to use to specify a particular Common
- Lisp implementation. Unfortunately, not every vendor has a
- unique keyword that distinguishes their family of implementations from
- those of other vendors, nor major and minor versions of the implementation.
-
- :lucid Lucid Common Lisp
- :lcl3.0 Lucid Common Lisp v3.0 and above
- :lcl4.0 Lucid Common Lisp v4.0 and above
- ----------------
- (and :allegro :franz-inc) Franz Allegro Common Lisp
- :excl Franz Allegro Common Lisp
- :aclpc Franz Allegro Common Lisp\PC.
- :allegro-v3.0 Franz Allegro Common Lisp v3.0
- :allegro-v3.1 Franz Allegro Common Lisp v3.1
- :allegro-v4.0 Franz Allegro Common Lisp v4.0
- :allegro-v4.1 Franz Allegro Common Lisp v4.1
- ----------------
- :cmu CMU Common Lisp
- (and :cmu :new-compiler) CMU Common Lisp w/Python compiler
- (and :cmu :python) CMU Common Lisp w/Python compiler
- :cmu17 CMU Common Lisp v17 and above
- ----------------
- kcl Kyoto Common Lisp
- akcl Austin KCL
- :ibcl Ibuki Common Lisp
- ----------------
- :mcl Macintosh Common Lisp
- :coral Coral Lisp; bought by Apple to become
- MACL, then MCL
- :ccl Coral Common Lisp
- [Note: Harlequin LispWorks also uses :ccl]
- :ccl-1 Coral Common Lisp v1
- :ccl-1.3 Coral Common Lisp v1.3 and higher
- :ccl-2 present in Macintosh Common Lisp 2.0 and higher
- ----------------
- :harlequin-common-lisp Harlequin Common Lisp
- :harlequin-unix-lisp Harlequin on Unix platforms
- :harlequin-PC-lisp Harlequin on PC platforms
- :lispworks Harlequin Lispworks development environment
- :lispworks3 major release of Harlequin Lispworks
- :lispworks3.1 major and minor release of Harlequin Lispworks
- :harlequin All Harlequin products. not always present?
- ----------------
- :clisp CLISP Common Lisp
- ----------------
- :symbolics Symbolics Genera
- :imach Symbolics Genera for Ivory architecture
- :cloe-runtime Symbolics CLOE
- :cloe CLOE 3.1
- ----------------
- :procyon Procyon Common Lisp
- (and :procyon :macintosh) Procyon Common Lisp, Macintosh version
- (and :procyon :os2) Procyon Common Lisp, OS2 version
- ----------------
- :gclisp Golden Common Lisp
- ----------------
- (and dec vax common) DEC VAXlisp
- ----------------
- :explorer TI Explorer Lisp Machine | used
- :TI TI Explorer Lisp Machine | interchangeably
- :elroy TI Explorer release 3 and successors
- ----------------
- :Xerox Medley (Venue's CL/InterLisp combo) to rel2.01
- :medley Medley releases 3.0 and up
- Use (IL:UNIX-GETPARM "mach") and (IL:UNIX-GETPARM "arch") to
- distinguish platforms under Medley.
- ----------------
- :ecl ECoLisp
- ----------------
- :lispm Symbolics, TI, and LMI Lisp machines
-
- In the cases where a feature is not a keyword, it is almost always
- in the LISP package.
-
- The draft ANSI standard defines some other useful features:
-
- :cltl1 Compatible with the 1st edition of Steele
- :cltl2 Compatible with the 2nd edition of Steele
- :IEEE-Floating-Point IEEE floating point support
- :X3J13 conforms to some particular draft of the ANSI
- CL specification
- :draft-ANSI-CL conforms to first full public review draft
- :ANSI-CL conforms to ANSI CL after its adoption
- :common-lisp language family "Common Lisp"
-
- Other features used by some Lisps include:
-
- :clos Contains a native CLOS implementation.
- :pcl Contains the PCL implementation of CLOS.
- :flavors Has an implementation of Symbolics Flavors
- :loop Contains the :cltl1 version of the Loop macro
- :ansi-loop Contains the ANSI Loop macro
- :clx or :xlib Contains CLX
- :clxr4 or :CLX-MIT-R4 Contains CLX for X11R4
- :clxr5 or :CLX-MIT-R5 Contains CLX for X11R5
- :compiler Contains a compiler
- :windows MS Windows version
- :color Color display
- :monochrome Monochrome display
- :multiprocessing Has multiprocessing capabilities.
- :profiler Has a PC-monitoring based profiler.
-
- Platform-specific features, CPU-dependent features, and
- operating-system specific features are also important because they can
- indicate changes between different implementations of the same lisp,
- such as compiled file extensions (e.g., .sbin, .hbin, etc.).
- Unfortunately, not every vendor includes such features, and the naming
- conventions are inconsistent. Where there are several names for the
- same feature, we've put the preferred name first. Hopefully the
- vendors will begin to standardize their use of these features.
- CPU-dependent features include :sparc (used in CMU CL, Lucid CL,
- Harlequin, and Allegro CL), :mips (used in Allegro CL), :r2000 (used
- in Allegro CL even on r4000 machines), :mc68000, and :pa (HP's
- 9000/800 RISC cpu). Platform-specific features include :sun (used in
- Allegro CL and Lucid), :sun4 (used in CMU CL and Allegro CL), :sgi
- (used in Allegro CL), :hp300, :hp400, :hp500, :sun3, :vax, :prime,
- :dec, :dec3100, :macintosh (used in Procyon but not MCL), :ibm-pc,
- :ibm-rt-pc. OS-specific features include :unix (used in CMU CL, IBCL,
- and Lucid CL), :vms, :sunos (used in CMU CL), :sun-os (used in Lucid),
- :sunos4.0 and :sunos4 (used in various Allegro versions independent of
- the actual version of SunOS), :mach (used in CMU CL), :hpux, :ultrix,
- :os2, and :svr4.
-
- Notes:
-
- :allegro alone doesn't suffice to distinguish Franz Allegro Common
- Lisp from Macintosh Allegro Common Lisp (an early version of
- Macintosh Common Lisp). :excl specifies that the EXCL package (a
- set of Allegro extensions to Common Lisp) is present, but this has
- since become synonymous with Franz Allegro Common Lisp.
-
- Thanks to Vincent Keunen for gathering the information in this list.
-
- ----------------------------------------------------------------
- Subject: [2-18] What reader macro characters are used in major Lisp systems?
-
- The draft ANSI standard for Common Lisp leaves many dispatching macro
- characters unassigned. Of these, the following are explicitly reserved
- for the user and hence will never be defined by Common Lisp:
- #!, #?, #[, #], #{, and #}.
- All other unassigned macro characters are not reserved for the user,
- and hence the user has no guarantee that they won't be used by some
- Lisp implementation.
-
- As a result, there is the potential of portability clashes between
- systems that use the same macro characters. This question lists the
- non-standard macro character usage of major Lisp systems, in an effort
- to avoid such conflicts.
-
- #" AKCL; pathnames
- #$ Macintosh Common Lisp; traps
- #% Cyc; references to constants in the representation language
- #% Harlequin Lispworks; ?
- #@ Macintosh Common Lisp; Points notation
- #@ Defsystem
- #I Portable Infix Package
- #L Allegro Common Lisp; logical pathnames
- #M Series
- #T Allegro Common Lisp; ?
- #Y CLISP; ?
- #Z Series
- #_ Macintosh Common Lisp; traps
- #` Harlequin Lispworks; ?
-
- There is a proposal in the ANSI draft to have COMPILE-FILE and LOAD
- bind *READTABLE*, which would allow one to locally redefine syntax
- through private readtables. Unfortunately, this doesn't help with the
- Infix Package, where one wants to globally extend syntax.
-
- ----------------------------------------------------------------
- Subject: [2-19] How do I determine if a file is a directory or not?
- How do I get the current directory name from within a Lisp
- program? Is there any way to create a directory?
-
- There is no portable way in Common Lisp of determining whether a file
- is a directory or not. Calling DIRECTORY on the pathname will not
- always work, since the directory could be empty. For UNIX systems
- (defun DIRECTORY-P (pathname)
- (probe-file (concatenate 'string pathname "/.")))
- seems to work fairly reliably. (If "foo" is a directory, then "foo/."
- will be a valid filename; if not, it will return NIL.) This won't, of
- course, work on the Macintosh, or on other operating systems (e.g.,
- MVS, CMS, ITS). On the Macintosh, use DIRECTORYP.
-
- Moreover, some operating systems may not support the concept of
- directories, or even of a file system. For example, recent work on
- object-oriented technology considers files to be collections of
- objects. Each type of collection defines a set of methods for reading
- and writing the objects "stored" in the collection.
-
-
- 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
- LispWorks: LW:*CURRENT-WORKING-DIRECTORY*
- (use LW:CHANGE-DIRECTORY to change it)
-
- 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.
-
- There is no portable way of creating a new directory from within a
- Lisp program.
-
- ----------------------------------------------------------------
- Subject: [2-20] What is a "Lisp Machine" (LISPM)?
-
- A Lisp machine (or LISPM) is a computer which has been optimized to run lisp
- efficiently and provide a good environment for programming in it. The
- original Lisp machines were implemented at MIT, with spinoffs as LMI (defunct)
- and Symbolics (bankrupt). Xerox also had a series of Lisp machines
- (Dandylion, Dandytiger), as did Texas Instruments (TI Explorer). The
- TI and Symbolics Lisp machines are currently available as cards that
- fit into Macintosh computers (the so-called "Lisp on a chip").
-
- Optimizations typical of Lisp machines include:
-
- - Hardware Type Checking. Special type bits let the type be checked
- efficiently at run-time.
-
- - Hardware Garbage Collection.
-
- - Fast Function Calls.
-
- - Efficient Representation of Lists.
-
- - System Software and Integrated Programming Environments.
-
- For further information, see:
-
- Paul Graham, "Anatomy of a Lisp Machine", AI Expert, December 1988.
-
- Pleszkun and Thazhuthaveetil, "The Architecture of Lisp Machines",
- IEEE Computer, March 1987.
-
- Ditzel, Schuler and Thomas, "A Lisp Machine Profile: Symbolics 3650",
- AI Expert, January 1987.
-
- Peter M. Kogge, "The Architecture of Symbolic Computers",
- McGraw-Hill 1991. ISBN 0-07-035596-7.
-
- [Derived from a post by Arthur Pendragon <apendragon@delphi.com>.]
-
- ----------------------------------------------------------------
- Subject: [2-21] How do I tell if a symbol names a function and not a macro?
-
- FBOUNDP tests whether the symbol is globally bound to an operator
- (e.g., a function, macro, or special form). SYMBOL-FUNCTION returns
- the contents of a symbol's "function slot" if the symbol names a
- function. But if the symbol names a macro or special form, it is
- completely unspecified what a call to SYMBOL-FUNCTION will return.
- Instead, use code like the following to test whether a symbol names a
- function:
-
- (defun fbound-to-function-p (symbol)
- (and (fboundp symbol)
- (not (macro-function symbol))
- (not (special-operator-p symbol))))
-
- ----------------------------------------------------------------
- ;;; *EOF*
-