- Dedication
- Credits
- Copyright
- Acknowledgments
- Foreword
- Introduction
- Chapter 1 - Why Bother? Or: Objections
Answered
Chapter objective: Describe the most common objections to Lisp, and answer
each with advice on state-of-the-art implementations and previews of what
this book will explain.
- I looked at Lisp before, and didn't understand it.
- I can't see the program for the parentheses.
- Lisp is very slow compared to my favorite language.
- No one else writes programs in Lisp.
- Lisp doesn't let me use graphical interfaces.
- I can't call other people's code from Lisp.
- Lisp's garbage collector causes unpredictable pauses when my program
runs.
- Lisp is a huge language.
- Lisp is only for artificial intelligence research.
- Lisp doesn't have any good programming tools.
- Lisp uses too much memory.
- Lisp uses too much disk space.
- I can't find a good Lisp compiler.
- Chapter 2 - Is this Book for Me?
Chapter objective: Describe how this book will benefit the reader, with
specific examples and references to chapter contents.
- The Professional Programmer
- The Student
- The Hobbyist
- The Former Lisp Acquaintance
- The Curious
- Chapter 3 - Essential Lisp in Twelve
Lessons
Chapter objective: Explain Lisp in its simplest form, without worrying
about the special cases that can confuse beginners.
- Lesson 1 - Essential Syntax
- Lists are surrounded by parentheses
- Atoms are separated by whitespace or parentheses
- Lesson 2 - Essential Evaluation
- A form is meant to be evaluated
- A function is applied to its arguments
- A function can return any number of values
- Arguments are usually not modified by a function
- Arguments are usually evaluated before function application
- Arguments are evaluated in left-to-right order
- Special forms and macros change argument evaluation
- Lesson 3 - Some Examples of Special Forms and Macros
- Lesson 4 - Putting things together, and taking them apart
- Lesson 5 - Naming and Identity
- A symbol is just a name
- A symbol is always unique
- A symbol can name a value
- A value can have more than one name
- Lesson 6 - Binding versus Assignment
- Binding creates a new place to hold a value
- Bindings have names
- A binding can have different values at the same time
- One binding is innermost
- The program can only access bindings it creates
- Assignment gives an old place a new value
- Lesson 7 - Essential Function Definition
- DEFUN defines named functions
- LAMBDA defines anonymous functions
- Lesson 8 - Essential Macro Definition
- DEFMACRO defines named macros
- Macros return a form, not values
- Lesson 9 - Essential Multiple Values
- Most forms create only one value
- VALUES creates multiple (or no) values
- A few special forms receive multiple values
- Most forms pass along multiple values
- Lesson 10 - A Preview of Other Data Types
- Lisp almost always does the right thing with numbers
- Characters give Lisp something to read and write
- Arrays organize data into tables
- Vectors are one-dimensional arrays
- Strings are vectors that contain only characters
- Symbols are unique, but they have many values
- Structures let you store related data
- Type information is apparent at runtime
- Hash Tables provide quick data access from a lookup key
- Packages keep names from colliding
- Lesson 11 - Essential Input and Output
- READ accepts Lisp data
- PRINT writes Lisp data for you and for READ
- OPEN and CLOSE let you work with files
- Variations on a PRINT theme
- Lesson 12 - Essential Reader Macros
- The reader turns characters into data
- Standard reader macros handle built-in data types
- User programs can define reader macros
- Chapter 4 - Mastering the Essentials
Chapter objective: Reinforce the concepts of Chapter 3 with hands-on
exercises.
- Hands-on! The "toploop"
- Spotting and avoiding common mistakes
- Defining simple functions
- Using global variables and constants
- Defining recursive functions
- Tail recursion
- Exercises in naming
- Lexical binding and multiple name spaces
- Reading, writing, and arithmetic
- Other data types
- Simple macros
- Reader macros
- Chapter 5 - Introducing Iteration
Chapter objective: Introduce the most common looping constructs.
"There's no such thing as an infinite loop. Eventually, the computer will
break." -- John D. Sullivan
- Simple LOOP loops forever...
- But there's a way out!
- Use DOTIMES for a counted loop
- Use DOLIST to process elements of a list
- DO is tricky, but powerful
- Chapter 6 - Deeper into Structures
Chapter objective: Show the most useful optional features of structures.
- Default values let you omit some initializers, sometimes
- Change the way Lisp prints your structures
- Alter the way structures are stored in memory
- Shorten slot accessor names
- Allocate new structures without using keyword arguments
- Define one structure as an extension of another
- Chapter 7 - A First Look at Objects as Fancy
Structures
Chapter objective: Introduce CLOS objects as tools for structuring data.
Object behaviors will be covered in a later chapter.
- Hierarchies: Classification vs. containment
- Use DEFCLASS to define new objects
- Objects have slots, with more options than structures
- Controlling access to a slot helps keep clients honest
- Override a slot accessor to do things that the client can't
- Define classes with single inheritance for specialization
- Multiple inheritance allows mix-and-match definition
- Options control initialization and provide documentation
- This is only the beginning...
- Chapter 8 - Lifetime and Visibility
Chapter objective: Show how lifetime and visibility affect the values of
Lisp variables during execution. This is pretty much like local and global
variables in other languages, but Lisp's special variables change things.
This chapter also sets the stage for understanding that lifetime and
visibility isn't just for variables.
- Everything in Lisp has both lifetime and visibility
- Lifetime: Creation, existence, then destruction
- Visibility: To see and to be seen by
- The technical names: Extent and Scope
- Really easy cases: top-level defining forms
- Scope and extent of parameters and LET variables
- Slightly trickier: special variables
- Chapter 9 - Introducing Error Handling and
Non-Local Exits
Chapter objective: Show three new ways of transferring control between
parts of a program.
- UNWIND-PROTECT: When it absolutely, positively has to run
- Gracious exits with BLOCK and RETURN-FROM
- Escape from anywhere (but not at any time) with CATCH and THROW
- Making sure files only stay open as long as needed
- Chapter 10 - How to Find Your Way Around,
Part 1
Chapter objective: Show how to find things in Lisp without resorting to
the manual.
- APROPOS: I don't remember the name, but I recognize the face
- DESCRIBE: Tell me more about yourself
- INSPECT: Open wide and say "Ah..."
- DOCUMENTATION: I know I wrote that down somewhere
- Chapter 11 - Destructive Modification
Chapter objective: Illustrate the difference between assignment and
binding, and show why assignment is harder to understand. Then explore
reasons for preferring the more difficult concept, and introduce functions
that use destructive modification.
- Simple assignment is destructive modification
- The risk of assignment
- Changing vs. copying: an issue of efficiency
- Modifying lists with destructive functions
- RPLACA, RPLACD, SETF ...; circularity
- Places vs. values: destructive functions don't always
have the desired side-effect
- Contrast e.g. PUSH and DELETE
- Shared and constant data: Dangers of destructive changes
- Chapter 12 - Mapping Instead of Iteration
Chapter objective: Categorize and demonstrate the mapping functions. Show
appropriate and inappropriate uses. Introduce the concept of sequences.
- MAPCAR, MAPC, and MAPCAN process successive list elements
- MAPLIST, MAPL, and MAPCON process successive sublists
- MAP and MAP-INTO work on sequences, not just lists
- Mapping functions are good for filtering
- It's better to avoid mapping if you care about efficiency
- Predicate mapping functions test sequences
- SOME, EVERY, NOTANY, NOTEVERY
- REDUCE combines sequence elements
- Chapter 13 - Still More Things You Can Do
with Sequences
Chapter objective: Introduce the most useful sequence functions, and show
how to use them. Show how destructive sequence functions must be used to
have the intended effect.
- CONCATENATE: new sequences from old
- ELT and SUBSEQ get what you want from any sequence (also, COPY-SEQ)
- REVERSE turns a sequence end-for-end (also, NREVERSE)
- LENGTH: size counts after all
- COUNT: when it's what's inside that matters
- REMOVE, SUBSTITUTE, and other sequence changers
- DELETE, REMOVE-DUPLICATES, DELETE-DUPLICATES, and NSUBSTITUTE
- FILL and REPLACE
- Locating things in sequences: POSITION, FIND, SEARCH, and MISMATCH
- SORT and MERGE round out the sequence toolkit
- Chapter 14 - Can Objects Really Behave
Themselves?
Chapter objective: Show how generic functions work. Describe multiple
dispatch, inheritance, and method combination. Preview the metaobject
protocol.
- Generic functions give objects their behaviors
- The line between methods and objects blurs for multimethods
- Methods on non-objects? So where does the method live?
- Generic functions work by dispatching on argument specializers
- Object inheritance matters after all; finding the applicable method
- Method combinations offer further choices
- Nothing is cast in stone; a peek at the metaobject protocol
- Chapter 15 - Closures
Chapter objective: Show how closures capture free variables for use in
other execution contexts. Demonstrate with some practical applications.
- Is it a function of the lifetime, or the lifetime of a function?
- How to spot a free variable, and what to do about it.
- Using closures to keep private, secure information.
- Functions that return functions, and how they differ from macros.
- Chapter 16 - How to Find Your Way Around,
Part 2
Chapter objective: Learn what the Lisp compiler does to your code, and
how to watch what your code does as it runs.
"DISASSEMBLE is your friend." -- Bill St. Clair
- DISASSEMBLE: I always wondered what they put inside those things...
- BREAK and backtrace: How did I end up here?
- TRACE and STEP: I'm watching you!
- Chapter 17 - Not All Comparisons are
Equal
Chapter objective: Tell how and why Lisp has so many different comparison
functions. Give guidelines for proper choice.
- The longer the test, the more it tells you
- EQ is true for identical symbols
- EQL is also true for identical numbers and characters
- EQUAL is usually true for things that print the same
- EQUALP ignores number type and character case
- Longer tests are slower; know what you're comparing
- Specialized tests run faster on more restricted data types
- Chapter 18 - Very Logical, Indeed...
Chapter objective: Describe common logical functions, and conditional
evaluation. Introduce bit manipulation functions, bit vectors, and
generalized byte manipulation.
- AND and OR evaluate only as much as they need
- Bits, bytes, and Boole
- Bit vectors can go on forever
- Chunks of bits make bytes
- Chapter 19 - Streams
Chapter objective: Introduce streams as generalized I/O facilities.
Emphasize interchangeability of streams attached to different devices.
- Streams provide a pipe to supply or accept data
- Creating streams on files
- Creating streams on strings
- Binary I/O
- Chapter 20 - Macro Etiquette
Chapter objective: Go beyond the simple examples of chapters 3 and 4 to
show how to properly construct macros to solve a wide variety of problems.
- Macros are programs that generate programs
- Close up: how macros work
- Backquote looks like a substitution template
- Beyond the obvious, part 1: compute, then generate
- Beyond the obvious, part 2: macros that define macros
- Tricks of the trade: elude capture using GENSYM
- Macros vs. inlining
- Chapter 21 - Fancy Tricks with Function and
Macro Arguments
Chapter objective: Describe lambda-list options. Show how they can be used
to clarify programs.
- Keywords let you name your parameters
- Default values for when you'd rather not say
- Add some structure to your macros by taking apart arguments
- Chapter 22 - How to Find Your Way Around,
Part 3
Chapter objective: Learn how to find out about objects and methods. Learn
specialized techniques to alter or monitor program behavior without
changing the source code.
- Class and method browsers help you find your way in a sea of objects
- ADVISE lets you modify a function's behavior without changing the
function
- WATCH lets you open a window on interesting variables
- Chapter 23 - To Err is Expected; To Recover,
Divine
Chapter objective: Show how to create your own error detection and
recovery mechanisms.
- Signal your own errors and impress your users
- Categorize errors using Conditions
- Recover from Conditions using Restarts
- Chapter 24 - FORMAT Speaks a Different
Language
Chapter objective: Describe the most useful functions of the FORMAT
function.
- FORMAT rhymes with FORTRAN, sort of...
- Formatting
- Iteration
- Conditionals
- Floobydust
- Chapter 25 - Connecting Lisp to the Real
World
Chapter objective: Describe FFI in general, and give examples from actual
implementations. Show how to use wrappers to call C++ functions. Show how
callbacks allow C programs to call Lisp functions. Give an example using
TCP/IP access.
- Foreign Function Interfaces let you talk to programs written in
"foreign languages"
- Would you wrap this, please?
- I'll call you back...
- Network Interfaces: beyond these four walls
- Chapter 26 - Put on a Happy Face: Interface
Builders
Chapter objective: Discuss event-driven interfaces and GUI builders in
general, then show examples from major desktop Common Lisp platforms.
Conclude with a discussion of platform-independent Lisp GUIs such as
Garnet and CLIM.
- Event-driven interfaces
- Graphical programming
- Example: MCL's Interface Toolkit
- Example: ACL4WIN's Interface Builder
- Example: Medley's ROOMS
- Platform-independent interfaces
- Chapter 27 - A Good Editor is Worth a
Thousand Keystrokes
Chapter objective: Show how Lisp's simple syntax combines with an
integrated editor to ease many of the common tasks of writing a Lisp
program.
- Simple syntax; smart editors
- Matching and flashing
- Automatic indentation
- Symbol completion
- Finding definitions
- On-line documentation
- Access to debugging tools
- Extending the editor using Lisp
- Chapter 28 - Practical Techniques for
Programming
Chapter objective: Provide useful guidelines for Lisp style. Give
practical advice on tradeoffs among debugging, performance, and
readability.
- Elements of Lisp style
- Property lists are handy for small (very small) ad-hoc databases
- Declarations help the compiler, sometimes
- DEFVAR versus DEFPARAMETER
- Define constants with DEFCONSTANT
- Know when (not) to use the compiler
- Speed vs. ability to debug
- Efficiency: spotting it, testing it
- Recognizing inefficiency, profiling; performance vs. readability
- Chapter 29 - I Thought it was Your Turn to
Take Out the Garbage
Chapter objective: Describe the benefits and costs of garbage collection.
Show how to improve program performance by reducing the amount of garbage
it generates.
- What is garbage?
- Why is garbage collection important?
- How does garbage collection work?
- What effect does garbage have on my program?
- How can I reduce garbage collection pauses in my program?
- Chapter 30 - Helpful Hints for Debugging and
Bug-Proofing
Chapter objective: Describe use of Lisp's debugging tools.
- Finding the cause of an error
- Reading backtraces, compiler settings for debugging
- Simple debugging tools
- BREAK, PRINT
- Power tools for tough problems
- TRACE, STEP, ADVISE, WATCH
- Into the belly of the beast
- INSPECT, DESCRIBE
- Continuing from an error
- Problems with unwanted definitions
- Package problems; method definitions
- The problem with macros
- Runtime tests catch "can't happen cases" when they do...
- Use method dispatch rather than case dispatch
- Chapter 31 - Handling Large Projects in
Lisp
Chapter objective: Describe strategies and tools used to organize Lisp
programs for large projects and team efforts.
- Packages keep your names separate from my names
- System builders let you describe dependencies
- Source control systems keep track of multiple revisions
- Modules: another way to describe file dependencies
- PROVIDE and REQUIRE
- Chapter 32 - Dark Corners and Curiosities
Chapter objective: Describe some Lisp features that are newer,
unstandardized, experimental, or controversial.
- Extended LOOP: Another little language
- TAGBODY: GO if you must
- Processes & Stack Groups: Juggling multiple tasks
- Series: Another approach to iteration and filtering
- Chapter 33 - Where to Go Next
Chapter objective: Provide pointers to other sources of information and
products.
- Suggestions for further reading
- On-line sources
- Commercial vendors
- Chapter 34 - Lisp History, or: Origins of
Misunderstandings
Chapter objective: Give a short history of Lisp's development, providing
insights to some lingering misconceptions.
- John McCarthy's Notation
- Earliest implementations
- Special hardware
- Diverging dialects
- The DARPA directive
- East vs. West, and European competition
- The emergence of compilers for stock hardware
- The long road to standardization
- State of the Art?
- Appendix A - Lisp System Feature
Comparison
Chapter objective: Describe several Common Lisp development systems, both
commercial and freeware. Compare and contrast. Note product and corporate
lineage.
- Digitool's Macintosh Common Lisp 3.0
- Franz's Allegro Common Lisp for Windows 2.0
- Venue's Medley 2.01
- David Betz's XLISP 2.1
- Roger Corman's PowerLisp 1.1
- xxx's CLISP ?.?
- Appendix B - Successful Lisp
Applications
Chapter objective: Describe large successful applications built in Lisp.