2363 lines
85 KiB
HTML
2363 lines
85 KiB
HTML
|
|
<!DOCTYPE HTML>
|
|
<html lang="" >
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
|
<title>Lists and List-Operations · Learn Lisp The Hard Way</title>
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
<meta name="description" content="">
|
|
<meta name="generator" content="GitBook 3.2.3">
|
|
<meta name="author" content=""the Phoeron" Colin J.E. Lupton">
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="gitbook/style.css">
|
|
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="gitbook/gitbook-plugin-hints/plugin-hints.css">
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="gitbook/gitbook-plugin-folding-chapters/folding-chapters.css">
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="gitbook/gitbook-plugin-highlight/website.css">
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="gitbook/gitbook-plugin-search/search.css">
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="gitbook/gitbook-plugin-fontsettings/website.css">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<meta name="HandheldFriendly" content="true"/>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
|
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
|
<link rel="apple-touch-icon-precomposed" sizes="152x152" href="gitbook/images/apple-touch-icon-precomposed-152.png">
|
|
<link rel="shortcut icon" href="gitbook/images/favicon.ico" type="image/x-icon">
|
|
|
|
|
|
<link rel="next" href="1-05-0-lookups-trees.html" />
|
|
|
|
|
|
<link rel="prev" href="1-03-0-getting-input-from-users.html" />
|
|
|
|
|
|
</head>
|
|
<body>
|
|
|
|
<div class="book">
|
|
<div class="book-summary">
|
|
|
|
|
|
<div id="book-search-input" role="search">
|
|
<input type="text" placeholder="Type to search" />
|
|
</div>
|
|
|
|
|
|
<nav role="navigation">
|
|
|
|
|
|
|
|
<ul class="summary">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="header">LEARN LISP THE HARD WAY</li>
|
|
|
|
|
|
|
|
<li class="chapter " data-level="1.1" data-path="./">
|
|
|
|
<a href="index.html">
|
|
|
|
|
|
Second Draft (in-progress)
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.2" data-path="CHANGELOG.html">
|
|
|
|
<a href="CHANGELOG.html">
|
|
|
|
|
|
CHANGELOG
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="1.3" data-path="TODO.html">
|
|
|
|
<a href="TODO.html">
|
|
|
|
|
|
TODO
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
<li class="header">PREFACE</li>
|
|
|
|
|
|
|
|
<li class="chapter " data-level="2.1" data-path="preface.html">
|
|
|
|
<a href="preface.html">
|
|
|
|
|
|
TANSTAAFL
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="2.2" data-path="preface-part-two.html">
|
|
|
|
<a href="preface-part-two.html">
|
|
|
|
|
|
The Hard Way is Easier
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="2.3" data-path="preface-part-three.html">
|
|
|
|
<a href="preface-part-three.html">
|
|
|
|
|
|
Who Is This Book For?
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="2.4" data-path="introduction.html">
|
|
|
|
<a href="introduction.html">
|
|
|
|
|
|
Lisp: A Future History
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="2.5" data-path="acknowledgements.html">
|
|
|
|
<a href="acknowledgements.html">
|
|
|
|
|
|
Acknowledgements
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
<li class="header">PART ONE</li>
|
|
|
|
|
|
|
|
<li class="chapter " data-level="3.1" data-path="1-0-0-overview.html">
|
|
|
|
<a href="1-0-0-overview.html">
|
|
|
|
|
|
Grokking Lisp
|
|
|
|
</a>
|
|
|
|
|
|
|
|
<ul class="articles">
|
|
|
|
|
|
<li class="chapter " data-level="3.1.1" data-path="1-01-00-lisp-bootcamp.html">
|
|
|
|
<a href="1-01-00-lisp-bootcamp.html">
|
|
|
|
|
|
Common Lisp Bootcamp
|
|
|
|
</a>
|
|
|
|
|
|
|
|
<ul class="articles">
|
|
|
|
|
|
<li class="chapter " data-level="3.1.1.1" data-path="1-01-01-syntax-overview.html">
|
|
|
|
<a href="1-01-01-syntax-overview.html">
|
|
|
|
|
|
Syntax Overview in 5 Minutes
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.1.2" data-path="1-01-02-repl.html">
|
|
|
|
<a href="1-01-02-repl.html">
|
|
|
|
|
|
The REPL
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.1.3" data-path="1-01-03-expressions.html">
|
|
|
|
<a href="1-01-03-expressions.html">
|
|
|
|
|
|
Expressions, Parentheses, and Return Values
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.1.4" data-path="1-01-04-lists-cons-cells.html">
|
|
|
|
<a href="1-01-04-lists-cons-cells.html">
|
|
|
|
|
|
Lists, Cons-Cells, and Memory
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.1.5" data-path="1-01-05-symbols.html">
|
|
|
|
<a href="1-01-05-symbols.html">
|
|
|
|
|
|
Symbols and Namespaces
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.1.6" data-path="1-01-06-prefix-notation.html">
|
|
|
|
<a href="1-01-06-prefix-notation.html">
|
|
|
|
|
|
Prefix Notation
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.1.7" data-path="1-01-07-style-guide.html">
|
|
|
|
<a href="1-01-07-style-guide.html">
|
|
|
|
|
|
Common Lisp Style Guide
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.1.8" data-path="1-01-08-configuration.html">
|
|
|
|
<a href="1-01-08-configuration.html">
|
|
|
|
|
|
Configuring Your Development Environment
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.2" data-path="1-02-00-input-output.html">
|
|
|
|
<a href="1-02-00-input-output.html">
|
|
|
|
|
|
Printing, Streams, and Strings
|
|
|
|
</a>
|
|
|
|
|
|
|
|
<ul class="articles">
|
|
|
|
|
|
<li class="chapter " data-level="3.1.2.1" data-path="1-02-01-strings.html">
|
|
|
|
<a href="1-02-01-strings.html">
|
|
|
|
|
|
Strings
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.2.2" data-path="1-02-02-more-strings.html">
|
|
|
|
<a href="1-02-02-more-strings.html">
|
|
|
|
|
|
More Strings
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.2.3" data-path="1-02-03-unicode.html">
|
|
|
|
<a href="1-02-03-unicode.html">
|
|
|
|
|
|
Unicode and Strings
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.2.4" data-path="1-02-04-chars.html">
|
|
|
|
<a href="1-02-04-chars.html">
|
|
|
|
|
|
Characters
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.2.5" data-path="1-02-05-more-chars.html">
|
|
|
|
<a href="1-02-05-more-chars.html">
|
|
|
|
|
|
More Characters
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.2.6" data-path="1-02-06-char-codes.html">
|
|
|
|
<a href="1-02-06-char-codes.html">
|
|
|
|
|
|
Character Codes
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.2.7" data-path="1-02-07-strings-from-chars.html">
|
|
|
|
<a href="1-02-07-strings-from-chars.html">
|
|
|
|
|
|
Strings from Chars
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.2.8" data-path="1-02-08-printing.html">
|
|
|
|
<a href="1-02-08-printing.html">
|
|
|
|
|
|
Printing
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.2.9" data-path="1-02-09-more-printing.html">
|
|
|
|
<a href="1-02-09-more-printing.html">
|
|
|
|
|
|
More Printing
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.2.10" data-path="1-02-10-prin1.html">
|
|
|
|
<a href="1-02-10-prin1.html">
|
|
|
|
|
|
Printing With prin1
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.2.11" data-path="1-02-11-princ.html">
|
|
|
|
<a href="1-02-11-princ.html">
|
|
|
|
|
|
Printing With princ
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.2.12" data-path="1-02-12-format.html">
|
|
|
|
<a href="1-02-12-format.html">
|
|
|
|
|
|
A Brief Introduction to Format
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.2.13" data-path="1-02-13-more-format.html">
|
|
|
|
<a href="1-02-13-more-format.html">
|
|
|
|
|
|
A Little Bit More on Format
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.2.14" data-path="1-02-14-pathnames.html">
|
|
|
|
<a href="1-02-14-pathnames.html">
|
|
|
|
|
|
Pathnames
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.2.15" data-path="1-02-15-streams.html">
|
|
|
|
<a href="1-02-15-streams.html">
|
|
|
|
|
|
Streams
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.2.16" data-path="1-02-16-file-streams.html">
|
|
|
|
<a href="1-02-16-file-streams.html">
|
|
|
|
|
|
File Streams
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.2.17" data-path="1-02-17-binary-streams.html">
|
|
|
|
<a href="1-02-17-binary-streams.html">
|
|
|
|
|
|
Binary Streams
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.2.18" data-path="1-02-18-prompting-users.html">
|
|
|
|
<a href="1-02-18-prompting-users.html">
|
|
|
|
|
|
Prompting Users
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.2.19" data-path="1-02-19-pretty-printing.html">
|
|
|
|
<a href="1-02-19-pretty-printing.html">
|
|
|
|
|
|
Pretty-Printing
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.3" data-path="1-03-0-getting-input-from-users.html">
|
|
|
|
<a href="1-03-0-getting-input-from-users.html">
|
|
|
|
|
|
Extra Credit: Getting Input from Users
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter active" data-level="3.1.4" data-path="1-04-0-lists.html">
|
|
|
|
<a href="1-04-0-lists.html">
|
|
|
|
|
|
Lists and List-Operations
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.5" data-path="1-05-0-lookups-trees.html">
|
|
|
|
<a href="1-05-0-lookups-trees.html">
|
|
|
|
|
|
Extra Credit: Look-up Lists and Trees
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.6" data-path="1-06-0-math.html">
|
|
|
|
<a href="1-06-0-math.html">
|
|
|
|
|
|
Numbers and Math
|
|
|
|
</a>
|
|
|
|
|
|
|
|
<ul class="articles">
|
|
|
|
|
|
<li class="chapter " data-level="3.1.6.1" data-path="1-06-01-integers.html">
|
|
|
|
<a href="1-06-01-integers.html">
|
|
|
|
|
|
Integers
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.6.2" data-path="1-06-02-more-integers.html">
|
|
|
|
<a href="1-06-02-more-integers.html">
|
|
|
|
|
|
More Integers
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.6.3" data-path="1-06-03-hexadecimal-notation.html">
|
|
|
|
<a href="1-06-03-hexadecimal-notation.html">
|
|
|
|
|
|
Hexadecimal Integer Notation
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.6.4" data-path="1-06-04-octal-notation.html">
|
|
|
|
<a href="1-06-04-octal-notation.html">
|
|
|
|
|
|
Octal Integer Notation
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.6.5" data-path="1-06-05-binary-notation.html">
|
|
|
|
<a href="1-06-05-binary-notation.html">
|
|
|
|
|
|
Binary Integer Notation
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.6.6" data-path="1-06-06-ratios.html">
|
|
|
|
<a href="1-06-06-ratios.html">
|
|
|
|
|
|
Ratios and Rational Numbers
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.6.7" data-path="1-06-07-floating-point.html">
|
|
|
|
<a href="1-06-07-floating-point.html">
|
|
|
|
|
|
Floating-point Numbers
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.6.8" data-path="1-06-08-constants.html">
|
|
|
|
<a href="1-06-08-constants.html">
|
|
|
|
|
|
Numeric Constants
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.6.9" data-path="1-06-09-complex-numbers.html">
|
|
|
|
<a href="1-06-09-complex-numbers.html">
|
|
|
|
|
|
Complex Numbers
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.6.10" data-path="1-06-10-arithmetic.html">
|
|
|
|
<a href="1-06-10-arithmetic.html">
|
|
|
|
|
|
Arithmetic
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.6.11" data-path="1-06-11-more-arithmetic.html">
|
|
|
|
<a href="1-06-11-more-arithmetic.html">
|
|
|
|
|
|
More Arithmetic
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.6.12" data-path="1-06-12-even-more-arithmetic.html">
|
|
|
|
<a href="1-06-12-even-more-arithmetic.html">
|
|
|
|
|
|
Even More Arithmetic
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.6.13" data-path="1-06-13-exponents.html">
|
|
|
|
<a href="1-06-13-exponents.html">
|
|
|
|
|
|
Exponents
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.6.14" data-path="1-06-14-logarithms.html">
|
|
|
|
<a href="1-06-14-logarithms.html">
|
|
|
|
|
|
Logarithms
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.6.15" data-path="1-06-15-trigonometry.html">
|
|
|
|
<a href="1-06-15-trigonometry.html">
|
|
|
|
|
|
Trigonometry
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.6.16" data-path="1-06-16-psuedorandom-numbers.html">
|
|
|
|
<a href="1-06-16-psuedorandom-numbers.html">
|
|
|
|
|
|
Pseudo-Random Numbers
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.7" data-path="1-07-0-arrays.html">
|
|
|
|
<a href="1-07-0-arrays.html">
|
|
|
|
|
|
Extra Credit: Arrays and Vectors
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.8" data-path="1-08-0-variables.html">
|
|
|
|
<a href="1-08-0-variables.html">
|
|
|
|
|
|
Variables, Parameters, and Constants
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.9" data-path="1-09-0-closures.html">
|
|
|
|
<a href="1-09-0-closures.html">
|
|
|
|
|
|
Extra Credit: Closures
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.10" data-path="1-10-0-functions.html">
|
|
|
|
<a href="1-10-0-functions.html">
|
|
|
|
|
|
Functions and Macros
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.11" data-path="1-11-0-text-adventure.html">
|
|
|
|
<a href="1-11-0-text-adventure.html">
|
|
|
|
|
|
Extra Credit: A Simple Text Adventure
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.12" data-path="1-12-0-namespaces.html">
|
|
|
|
<a href="1-12-0-namespaces.html">
|
|
|
|
|
|
Namespaces, Symbols, Packages, and Systems
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.13" data-path="1-13-0-simple-web-app.html">
|
|
|
|
<a href="1-13-0-simple-web-app.html">
|
|
|
|
|
|
Extra Credit: A Simple Web Application
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.14" data-path="1-14-0-conditionals.html">
|
|
|
|
<a href="1-14-0-conditionals.html">
|
|
|
|
|
|
Conditionals
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.15" data-path="1-15-0-command-line-utility.html">
|
|
|
|
<a href="1-15-0-command-line-utility.html">
|
|
|
|
|
|
Extra Credit: Command-Line Utilities
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.16" data-path="1-16-0-map-loop.html">
|
|
|
|
<a href="1-16-0-map-loop.html">
|
|
|
|
|
|
Mapping and Looping
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.17" data-path="1-17-0-iterate.html">
|
|
|
|
<a href="1-17-0-iterate.html">
|
|
|
|
|
|
Extra Credit: Revisiting Loops with Iterate
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.18" data-path="1-18-0-format.html">
|
|
|
|
<a href="1-18-0-format.html">
|
|
|
|
|
|
Format Strings
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.19" data-path="1-19-0-dsl.html">
|
|
|
|
<a href="1-19-0-dsl.html">
|
|
|
|
|
|
Extra Credit: Domain Specific Languages
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="3.1.20" data-path="1-20-0-review.html">
|
|
|
|
<a href="1-20-0-review.html">
|
|
|
|
|
|
Part One in Review
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
<li class="header">PART TWO</li>
|
|
|
|
|
|
|
|
<li class="chapter " data-level="4.1" data-path="2-0-0-overview.html">
|
|
|
|
<a href="2-0-0-overview.html">
|
|
|
|
|
|
The Suffusion of Blue
|
|
|
|
</a>
|
|
|
|
|
|
|
|
<ul class="articles">
|
|
|
|
|
|
<li class="chapter " data-level="4.1.1" data-path="2-01-0-programming-paradigms.html">
|
|
|
|
<a href="2-01-0-programming-paradigms.html">
|
|
|
|
|
|
Programming Paradigms
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="4.1.2" data-path="2-02-0-regex.html">
|
|
|
|
<a href="2-02-0-regex.html">
|
|
|
|
|
|
Extra Credit: Regular Expressions
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="4.1.3" data-path="2-03-0-objects-control.html">
|
|
|
|
<a href="2-03-0-objects-control.html">
|
|
|
|
|
|
Objects and Control Structures
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="4.1.4" data-path="2-04-0-data-persistence.html">
|
|
|
|
<a href="2-04-0-data-persistence.html">
|
|
|
|
|
|
Extra Credit: Persistence and Databases
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="4.1.5" data-path="2-05-0-extended-types.html">
|
|
|
|
<a href="2-05-0-extended-types.html">
|
|
|
|
|
|
Extended Types
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="4.1.6" data-path="2-06-0-threads-memos-parallel.html">
|
|
|
|
<a href="2-06-0-threads-memos-parallel.html">
|
|
|
|
|
|
Extra Credit: Concurrency and Memoization
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="4.1.7" data-path="2-07-0-logic-and-more-math.html">
|
|
|
|
<a href="2-07-0-logic-and-more-math.html">
|
|
|
|
|
|
Logic and Advanced Math
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="4.1.8" data-path="2-08-0-number-theory.html">
|
|
|
|
<a href="2-08-0-number-theory.html">
|
|
|
|
|
|
Extra Credit: Number Theory
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="4.1.9" data-path="2-09-0-binary-octets-bits.html">
|
|
|
|
<a href="2-09-0-binary-octets-bits.html">
|
|
|
|
|
|
Binary Streams, Octet-Vectors, and Bit-Vectors
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="4.1.10" data-path="2-10-0-improved-text-adventure-engine.html">
|
|
|
|
<a href="2-10-0-improved-text-adventure-engine.html">
|
|
|
|
|
|
Extra Credit: An Improved Text Adventure Engine
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="4.1.11" data-path="2-11-0-conditions.html">
|
|
|
|
<a href="2-11-0-conditions.html">
|
|
|
|
|
|
Conditions and Error Handling
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="4.1.12" data-path="2-12-0-2d-game.html">
|
|
|
|
<a href="2-12-0-2d-game.html">
|
|
|
|
|
|
Extra Credit: Write a 2D Game
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="4.1.13" data-path="2-13-0-compiler.html">
|
|
|
|
<a href="2-13-0-compiler.html">
|
|
|
|
|
|
The Compiler
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="4.1.14" data-path="2-14-0-tree-shaker.html">
|
|
|
|
<a href="2-14-0-tree-shaker.html">
|
|
|
|
|
|
Extra Credit: Write a Tree-Shaker
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="4.1.15" data-path="2-15-0-docs-and-inspection.html">
|
|
|
|
<a href="2-15-0-docs-and-inspection.html">
|
|
|
|
|
|
Documentation and Inspection
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="4.1.16" data-path="2-16-0-foreign-libs.html">
|
|
|
|
<a href="2-16-0-foreign-libs.html">
|
|
|
|
|
|
Extra Credit: Foreign Libraries in Lisp
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="4.1.17" data-path="2-17-0-debugging-testing.html">
|
|
|
|
<a href="2-17-0-debugging-testing.html">
|
|
|
|
|
|
Debugging and Unit Testing
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="4.1.18" data-path="2-18-0-ffi.html">
|
|
|
|
<a href="2-18-0-ffi.html">
|
|
|
|
|
|
Extra Credit: Write a Foreign Function Interface
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="4.1.19" data-path="2-19-0-essential-libs.html">
|
|
|
|
<a href="2-19-0-essential-libs.html">
|
|
|
|
|
|
Essential Lisp Libraries
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="4.1.20" data-path="2-20-0-packaging-libs.html">
|
|
|
|
<a href="2-20-0-packaging-libs.html">
|
|
|
|
|
|
Extra Credit: Packaging Lisp Libraries
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="4.1.21" data-path="2-21-0-review.html">
|
|
|
|
<a href="2-21-0-review.html">
|
|
|
|
|
|
Detailed Syntax Review
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
<li class="header">PART THREE</li>
|
|
|
|
|
|
|
|
<li class="chapter " data-level="5.1" data-path="3-00-00-overview.html">
|
|
|
|
<a href="3-00-00-overview.html">
|
|
|
|
|
|
Lisp So(u)rcery
|
|
|
|
</a>
|
|
|
|
|
|
|
|
<ul class="articles">
|
|
|
|
|
|
<li class="chapter " data-level="5.1.1" data-path="3-01-00-web-apps.html">
|
|
|
|
<a href="3-01-00-web-apps.html">
|
|
|
|
|
|
Real-world Web Apps
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="5.1.2" data-path="3-02-00-typesetting.html">
|
|
|
|
<a href="3-02-00-typesetting.html">
|
|
|
|
|
|
Typesetting
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="5.1.3" data-path="3-03-00-mobile.html">
|
|
|
|
<a href="3-03-00-mobile.html">
|
|
|
|
|
|
Native Mobile Applications
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="5.1.4" data-path="3-04-00-gui.html">
|
|
|
|
<a href="3-04-00-gui.html">
|
|
|
|
|
|
Cross-platform Desktop Applications
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="5.1.5" data-path="3-05-00-system-utils.html">
|
|
|
|
<a href="3-05-00-system-utils.html">
|
|
|
|
|
|
Drivers, Daemons, and System-Utilities
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="5.1.6" data-path="3-06-00-reverse-engineering.html">
|
|
|
|
<a href="3-06-00-reverse-engineering.html">
|
|
|
|
|
|
Reverse Engineering
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="5.1.7" data-path="3-07-00-graphics.html">
|
|
|
|
<a href="3-07-00-graphics.html">
|
|
|
|
|
|
Graphics Rendering
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="5.1.8" data-path="3-08-00-gaming.html">
|
|
|
|
<a href="3-08-00-gaming.html">
|
|
|
|
|
|
OpenGL, SDL, and 3D Game Development
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="5.1.9" data-path="3-09-00-audio.html">
|
|
|
|
<a href="3-09-00-audio.html">
|
|
|
|
|
|
Audio Generation and Manipulation
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="5.1.10" data-path="3-10-00-data.html">
|
|
|
|
<a href="3-10-00-data.html">
|
|
|
|
|
|
Data Aggregation and Analysis
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="5.1.11" data-path="3-11-00-cryptosec.html">
|
|
|
|
<a href="3-11-00-cryptosec.html">
|
|
|
|
|
|
Cryptography and Security
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="5.1.12" data-path="3-12-00-fintech.html">
|
|
|
|
<a href="3-12-00-fintech.html">
|
|
|
|
|
|
Financial Software and Crypto-Currencies
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="5.1.13" data-path="3-13-00-scientific-computing.html">
|
|
|
|
<a href="3-13-00-scientific-computing.html">
|
|
|
|
|
|
Scientific Computing
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="5.1.14" data-path="3-14-00-computational-physics.html">
|
|
|
|
<a href="3-14-00-computational-physics.html">
|
|
|
|
|
|
Computational Physics
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="5.1.15" data-path="3-15-00-quantum-computing.html">
|
|
|
|
<a href="3-15-00-quantum-computing.html">
|
|
|
|
|
|
Quantum Computing
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="5.1.16" data-path="3-16-00-nlp.html">
|
|
|
|
<a href="3-16-00-nlp.html">
|
|
|
|
|
|
Natural Language Processing
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="5.1.17" data-path="3-17-00-ai.html">
|
|
|
|
<a href="3-17-00-ai.html">
|
|
|
|
|
|
Artificial Intelligence
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="5.1.18" data-path="3-18-00-robotics.html">
|
|
|
|
<a href="3-18-00-robotics.html">
|
|
|
|
|
|
Robotics
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="5.1.19" data-path="3-19-00-space-tech.html">
|
|
|
|
<a href="3-19-00-space-tech.html">
|
|
|
|
|
|
Space Tech
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="5.1.20" data-path="3-20-00-neurotech.html">
|
|
|
|
<a href="3-20-00-neurotech.html">
|
|
|
|
|
|
Neuroscience and Thought-Controlled Computing
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="5.1.21" data-path="3-21-00-lispos.html">
|
|
|
|
<a href="3-21-00-lispos.html">
|
|
|
|
|
|
A Simple LispOS
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="5.1.22" data-path="3-22-00-lisp-machine.html">
|
|
|
|
<a href="3-22-00-lisp-machine.html">
|
|
|
|
|
|
Build Your Own Lisp Machine
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
<li class="chapter " data-level="5.1.23" data-path="3-23-00-gov-mil.html">
|
|
|
|
<a href="3-23-00-gov-mil.html">
|
|
|
|
|
|
Government and Military Grade Systems
|
|
|
|
</a>
|
|
|
|
|
|
|
|
</li>
|
|
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
<li class="divider"></li>
|
|
|
|
<li>
|
|
<a href="https://www.gitbook.com" target="blank" class="gitbook-link">
|
|
Published with GitBook
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
|
|
|
|
</nav>
|
|
|
|
|
|
</div>
|
|
|
|
<div class="book-body">
|
|
|
|
<div class="body-inner">
|
|
|
|
|
|
|
|
<div class="book-header" role="navigation">
|
|
|
|
|
|
<!-- Title -->
|
|
<h1>
|
|
<i class="fa fa-circle-o-notch fa-spin"></i>
|
|
<a href="index.html" >Lists and List-Operations</a>
|
|
</h1>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="page-wrapper" tabindex="-1" role="main">
|
|
<div class="page-inner">
|
|
|
|
<div id="book-search-results">
|
|
<div class="search-noresults">
|
|
|
|
<section class="normal markdown-section">
|
|
|
|
<h1 id="chapter-14">Chapter 1.4</h1>
|
|
<h2 id="lists-and-list-operations">Lists and List Operations</h2>
|
|
<blockquote>
|
|
<p>"While the laws of statistics tell you how unlikely a particular coincidence is, they state just as firmly that coincidences <em>do happen</em>."</p>
|
|
<footer>Robert A. Heinlein, <em>The Door Into Summer</em></footer>
|
|
|
|
</blockquote>
|
|
<p>In the spirit of Lambda Calculus and a pure functional heritage, the Lisp-family of programming languages gets its name from its purpose---<em>LISt Processing</em>. Even though Common Lisp is not a purely-functional programming language, its fundamental syntax has not deviated from this heritage; as you should remember from Chapter 1.1, Cons-Cells are one of two essential forms of Expressions in Lisp, and they are represented using List syntax; and since the other---Atoms---are, by definition, self-evaluating, everything interesting that you can do in Lisp is <em>effectively</em> a List operation. And these are divided into <em>consing</em> and <em>non-consing</em> operations.</p>
|
|
<p>This is important to remember---it's the reason there are <em>so many</em> parentheses in Lisp source-code. Every form surrounded by parentheses is a list. The only difference between code and data, syntactically speaking, is that <em>code is read and evaluated</em> whereas <em>data is only read</em>; you can switch to "data mode" by quoting an expression, but quoting isn't a free pass. Lisp still expects to be able to <em>Read</em> the forms you've quoted as valid forms, so the syntax is just as important to data as it is to code.</p>
|
|
<p>This is also the key to Lisp's homoiconicity---the same syntax is used to represent both Code and Data, and as a result you can treat Code as Data, and Data as Code. As far as Lisp is concerned, there is no difference between the two.</p>
|
|
<p>But Lists are also a proper type in Common Lisp, that descends from sequences. We have already seen some sequence operations on other data types, like Strings, and will explore them further. However, in this chapter, we will focus on Lists as a proper data type and Consing operations on these Lists.</p>
|
|
<ul>
|
|
<li>Consing and Cons-Cells</li>
|
|
<li>The LIST Function</li>
|
|
<li>CAR and CDR</li>
|
|
<li>FIRST, REST, and LAST</li>
|
|
<li>PUSH and POP</li>
|
|
<li>List Position</li>
|
|
<li>APPEND</li>
|
|
<li>Quoting</li>
|
|
<li>Circular Lists</li>
|
|
<li>Circular Trees</li>
|
|
</ul>
|
|
<h3 id="exercise-141">Exercise 1.4.1</h3>
|
|
<p><strong>Cons-Cells</strong></p>
|
|
<p>Cons-Cells are the smallest compound data structure in Lisp. A Cons-Cell is effectively a pair of pointers. You can tell if what you're looking at is a Cons-Cell by using the predicate <code>consp</code>.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">consp</span> <span class="hljs-number">5</span>)
|
|
NIL
|
|
|
|
* (<span class="hljs-name">consp</span> <span class="hljs-string">"a"</span>)
|
|
NIL
|
|
|
|
* (<span class="hljs-name">consp</span> 'a)
|
|
NIL
|
|
|
|
* (<span class="hljs-name">consp</span> (<span class="hljs-name">cons</span> 'a 'b))
|
|
T
|
|
</code></pre>
|
|
<h3 id="exercise-142">Exercise 1.4.2</h3>
|
|
<p><strong>Consing</strong></p>
|
|
<p>One way to create a Cons-Cell is using the <code>cons</code> function.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">cons</span> 'a 'b)
|
|
(<span class="hljs-name">A</span> . B)
|
|
</code></pre>
|
|
<p>They can hold any <code>type</code> of data, not just symbols.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">cons</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span>)
|
|
(<span class="hljs-number">1</span> . <span class="hljs-number">2</span>)
|
|
|
|
* (<span class="hljs-name">cons</span> <span class="hljs-string">"one"</span> <span class="hljs-string">"two"</span>)
|
|
(<span class="hljs-string">"one"</span> . <span class="hljs-string">"two"</span>)
|
|
</code></pre>
|
|
<h3 id="exercise-143">Exercise 1.4.3</h3>
|
|
<p><strong>Dot-Notation</strong></p>
|
|
<p>You can see that when we cons two atoms together, we get back a Dotted Pair. This is a <code>read</code>able representation of Cons-Cells. That is, you can use it directly, rather than calling <code>cons</code>.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">cons</span> 'a 'b)
|
|
(<span class="hljs-name">A</span> . B)
|
|
|
|
* '(a . b)
|
|
(<span class="hljs-name">A</span> . B)
|
|
</code></pre>
|
|
<p>These two representations are equivalent.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">equal</span> (<span class="hljs-name">cons</span> 'a 'b) '(a . b))
|
|
T
|
|
</code></pre>
|
|
<h3 id="exercise-144">Exercise 1.4.4</h3>
|
|
<p><strong>More Consing</strong></p>
|
|
<p>Cons-Cells need not contain homogenous data.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">cons</span> 'a <span class="hljs-number">2</span>)
|
|
(<span class="hljs-name">A</span> . <span class="hljs-number">2</span>)
|
|
|
|
* (<span class="hljs-name">cons</span> <span class="hljs-number">1</span> <span class="hljs-string">"two"</span>)
|
|
(<span class="hljs-number">1</span> . <span class="hljs-string">"two"</span>)
|
|
|
|
* (<span class="hljs-name">cons</span> <span class="hljs-string">"a"</span> 'b)
|
|
(<span class="hljs-string">"a"</span> . B)
|
|
</code></pre>
|
|
<h3 id="exercise-145">Exercise 1.4.5</h3>
|
|
<p><strong>CAR and CDR</strong></p>
|
|
<p>Using Cons-Cells as building blocks would be kind of pointless if we couldn't get their components back out. To get the value of the first slot in a Cons-Cell, we use the <code>car</code> function.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">cons</span> 'a 'b)
|
|
(<span class="hljs-name">A</span> . B)
|
|
|
|
* (<span class="hljs-name">car</span> (<span class="hljs-name">cons</span> 'a 'b))
|
|
A
|
|
</code></pre>
|
|
<p>Similarly, we can get the value from the second slot in a Cons-Cell using <code>cdr</code>.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">cons</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span>)
|
|
(<span class="hljs-number">1</span> . <span class="hljs-number">2</span>)
|
|
|
|
* (<span class="hljs-name">cdr</span> (<span class="hljs-name">cons</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span>))
|
|
<span class="hljs-number">2</span>
|
|
</code></pre>
|
|
<h3 id="exercise-146">Exercise 1.4.6</h3>
|
|
<p><strong>More CAR and CDR</strong></p>
|
|
<p><code>cons</code>, <code>car</code> and <code>cdr</code> are purely functional. Which means they never mutate their arguments.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">defvar</span> *a* (<span class="hljs-name">cons</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span>))
|
|
*A*
|
|
|
|
* *a*
|
|
(<span class="hljs-number">1</span> . <span class="hljs-number">2</span>)
|
|
|
|
* (<span class="hljs-name">cdr</span> *a*)
|
|
<span class="hljs-number">2</span>
|
|
|
|
* *a*
|
|
(<span class="hljs-number">1</span> . <span class="hljs-number">2</span>)
|
|
|
|
* (<span class="hljs-name">cons</span> <span class="hljs-number">3</span> (<span class="hljs-name">cdr</span> *a*))
|
|
(<span class="hljs-number">3</span> . <span class="hljs-number">2</span>)
|
|
|
|
* *a*
|
|
(<span class="hljs-number">1</span> . <span class="hljs-number">2</span>)
|
|
</code></pre>
|
|
<p>It is an error to use <code>car</code> and <code>cdr</code> on something other than a Cons-Cell.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">car</span> <span class="hljs-number">1</span>)
|
|
<span class="hljs-comment">; Evaluation aborted on #<TYPE-ERROR expected-type: LIST datum: 1></span>
|
|
|
|
* (<span class="hljs-name">cdr</span> 'a)
|
|
<span class="hljs-comment">; Evaluation aborted on #<TYPE-ERROR expected-type: LIST datum: A>.</span>
|
|
</code></pre>
|
|
<p>This includes other compound values such as strings and vectors</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">car</span> <span class="hljs-string">"a"</span>)
|
|
<span class="hljs-comment">; Evaluation aborted on #<TYPE-ERROR expected-type: LIST datum: "a">.</span>
|
|
|
|
* (<span class="hljs-name">cdr</span> #(<span class="hljs-number">1</span> <span class="hljs-number">2</span>))
|
|
<span class="hljs-comment">; Evaluation aborted on #<TYPE-ERROR expected-type: LIST datum: #<(SIMPLE-VECTOR 2) {1007D4C76F}>>.</span>
|
|
</code></pre>
|
|
<p>but not the empty list, also represented as <code>NIL</code></p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">car</span> <span class="hljs-literal">nil</span>)
|
|
NIL
|
|
|
|
* (<span class="hljs-name">cdr</span> <span class="hljs-literal">nil</span>)
|
|
NIL
|
|
|
|
* (<span class="hljs-name">car</span> ())
|
|
NIL
|
|
|
|
* (<span class="hljs-name">cdr</span> ())
|
|
NIL
|
|
</code></pre>
|
|
<h3 id="exercise-147">Exercise 1.4.7</h3>
|
|
<p><strong>Lists</strong></p>
|
|
<p>A list is either the empty list, or a chain of Cons-Cells ending with the empty list.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">listp</span> <span class="hljs-literal">nil</span>)
|
|
T
|
|
|
|
* (<span class="hljs-name">listp</span> (<span class="hljs-name">cons</span> <span class="hljs-number">5</span> <span class="hljs-literal">nil</span>))
|
|
T
|
|
</code></pre>
|
|
<p>If you cons something onto the empty list, you get the list of that thing.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">cons</span> <span class="hljs-number">5</span> <span class="hljs-literal">nil</span>)
|
|
(<span class="hljs-number">5</span>)
|
|
</code></pre>
|
|
<p>We can exploit the Cons-Cells' ability to contain heterogenous data in order to represent linked lists or trees.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">cons</span> <span class="hljs-number">3</span> (<span class="hljs-name">cons</span> <span class="hljs-number">2</span> (<span class="hljs-name">cons</span> <span class="hljs-number">1</span> <span class="hljs-literal">nil</span>)))
|
|
(<span class="hljs-number">3</span> <span class="hljs-number">2</span> <span class="hljs-number">1</span>)
|
|
</code></pre>
|
|
<h3 id="exercise-148">Exercise 1.4.8</h3>
|
|
<p><strong>More Lists</strong></p>
|
|
<p>Another way to create lists is using the <code>list</code> function.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">list</span> <span class="hljs-number">3</span> <span class="hljs-number">2</span> <span class="hljs-number">1</span>)
|
|
(<span class="hljs-number">3</span> <span class="hljs-number">2</span> <span class="hljs-number">1</span>)
|
|
</code></pre>
|
|
<p>The expression <code>(list a b ...)</code> is effectively shorthand for the expression <code>(cons a (cons b ...))</code>, with the final value being <code>cons</code>ed onto <code>NIL</code>.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">list</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span>)
|
|
(<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span>)
|
|
|
|
* (<span class="hljs-name">cons</span> <span class="hljs-number">1</span> (<span class="hljs-name">cons</span> <span class="hljs-number">2</span> (<span class="hljs-name">cons</span> <span class="hljs-number">3</span> <span class="hljs-literal">nil</span>)))
|
|
(<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span>)
|
|
|
|
* (<span class="hljs-name">equal</span> (<span class="hljs-name">list</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span>) (<span class="hljs-name">cons</span> <span class="hljs-number">1</span> (<span class="hljs-name">cons</span> <span class="hljs-number">2</span> (<span class="hljs-name">cons</span> <span class="hljs-number">3</span> <span class="hljs-literal">nil</span>))))
|
|
T
|
|
</code></pre>
|
|
<p>As with <code>cons</code>, it's possible to build up trees, rather than merely lists, using <code>list</code>.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">list</span> <span class="hljs-number">1</span> (<span class="hljs-name">list</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span>) (<span class="hljs-name">list</span> <span class="hljs-number">4</span> (<span class="hljs-name">list</span> (<span class="hljs-name">list</span> <span class="hljs-number">5</span>) <span class="hljs-number">6</span> <span class="hljs-number">7</span> <span class="hljs-number">8</span>)))
|
|
(<span class="hljs-number">1</span> (<span class="hljs-number">2</span> <span class="hljs-number">3</span>) (<span class="hljs-number">4</span> ((<span class="hljs-number">5</span>) <span class="hljs-number">6</span> <span class="hljs-number">7</span> <span class="hljs-number">8</span>)))
|
|
</code></pre>
|
|
<h3 id="exercise-149">Exercise 1.4.9</h3>
|
|
<p><strong>Even More CAR and CDR</strong></p>
|
|
<p>Because <code>car</code> and <code>cdr</code> are purely functional, and return their target value, it's possible to chain them in order to look into nested structures.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">cons</span> (<span class="hljs-name">cons</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span>) <span class="hljs-number">3</span>)
|
|
((<span class="hljs-number">1</span> . <span class="hljs-number">2</span>) . <span class="hljs-number">3</span>)
|
|
|
|
* (<span class="hljs-name">car</span> (<span class="hljs-name">car</span> (<span class="hljs-name">cons</span> (<span class="hljs-name">cons</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span>) <span class="hljs-number">3</span>)))
|
|
<span class="hljs-number">1</span>
|
|
</code></pre>
|
|
<p>This also applies to deeply nested lists.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">defparameter</span> *tree* (<span class="hljs-name">list</span> <span class="hljs-number">1</span> (<span class="hljs-name">list</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span>) (<span class="hljs-name">list</span> <span class="hljs-number">4</span> (<span class="hljs-name">list</span> (<span class="hljs-name">list</span> <span class="hljs-number">5</span>) <span class="hljs-number">6</span> <span class="hljs-number">7</span> <span class="hljs-number">8</span>))))
|
|
*tree*
|
|
|
|
* *tree*
|
|
(<span class="hljs-number">1</span> (<span class="hljs-number">2</span> <span class="hljs-number">3</span>) (<span class="hljs-number">4</span> ((<span class="hljs-number">5</span>) <span class="hljs-number">6</span> <span class="hljs-number">7</span> <span class="hljs-number">8</span>)))
|
|
|
|
* (<span class="hljs-name">car</span> (<span class="hljs-name">cdr</span> (<span class="hljs-name">car</span> (<span class="hljs-name">cdr</span> *tree*))))
|
|
<span class="hljs-number">3</span>
|
|
</code></pre>
|
|
<p>This is common enough that Lisp supports shorthand for such tree selections.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">car</span> *tree*)
|
|
<span class="hljs-number">1</span>
|
|
|
|
* (<span class="hljs-name">cadr</span> *tree*)
|
|
|
|
(<span class="hljs-number">2</span> <span class="hljs-number">3</span>)
|
|
|
|
* (<span class="hljs-name">cadadr</span> *tree*)
|
|
<span class="hljs-number">3</span>
|
|
|
|
* (<span class="hljs-name">cddr</span> *tree*)
|
|
((<span class="hljs-number">4</span> ((<span class="hljs-number">5</span>) <span class="hljs-number">6</span> <span class="hljs-number">7</span> <span class="hljs-number">8</span>)))
|
|
|
|
* (<span class="hljs-name">cdddr</span> *tree*)
|
|
NIL
|
|
</code></pre>
|
|
<p>They're actual functions though. Not a reader syntax based on the number of <code>a</code>s and <code>d</code> s between the <code>c</code> and <code>r</code>. So, for instance:</p>
|
|
<pre><code class="lang-lisp">* (caddadddaaar *tree*)
|
|
The function COMMON-LISP-USER::CADDADDDAAAR is undefined.
|
|
[Condition of type UNDEFINED-FUNCTION]
|
|
</code></pre>
|
|
<h3 id="exercise-1410">Exercise 1.4.10</h3>
|
|
<p><strong>Push and Pop</strong></p>
|
|
<p>We mentioned before that <code>cons</code>, <code>car</code>, <code>cdr</code> and friends are purely functional. But, sometimes, you want to destructively modify a list you've defined. For instance, in order to implement a mutable stack. In order to destructively <code>cons</code> elements onto a list, use <code>push</code>.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">defvar</span> *stack* <span class="hljs-literal">nil</span>)
|
|
*stack*
|
|
|
|
* (<span class="hljs-name">push</span> <span class="hljs-number">1</span> *stack*)
|
|
(<span class="hljs-number">1</span>)
|
|
|
|
* *stack*
|
|
(<span class="hljs-number">1</span>)
|
|
|
|
* (<span class="hljs-name">push</span> <span class="hljs-number">2</span> *stack*)
|
|
(<span class="hljs-number">2</span> <span class="hljs-number">1</span>)
|
|
|
|
* (<span class="hljs-name">push</span> <span class="hljs-number">3</span> *stack*)
|
|
(<span class="hljs-number">3</span> <span class="hljs-number">2</span> <span class="hljs-number">1</span>)
|
|
|
|
* *stack*
|
|
(<span class="hljs-number">3</span> <span class="hljs-number">2</span> <span class="hljs-number">1</span>)
|
|
</code></pre>
|
|
<h3 id="exercise-1411">Exercise 1.4.11</h3>
|
|
<p><strong>Pop</strong></p>
|
|
<p>The other half of the a stack involves destructively removing the first element from it. This can be done with <code>pop</code>.</p>
|
|
<pre><code class="lang-lisp">* *stack*
|
|
(<span class="hljs-number">3</span> <span class="hljs-number">2</span> <span class="hljs-number">1</span>)
|
|
|
|
* (<span class="hljs-name">pop</span> *stack*)
|
|
<span class="hljs-number">3</span>
|
|
|
|
* *stack*
|
|
(<span class="hljs-number">2</span> <span class="hljs-number">1</span>)
|
|
|
|
* (<span class="hljs-name">pop</span> *stack*)
|
|
<span class="hljs-number">2</span>
|
|
|
|
* (<span class="hljs-name">pop</span> *stack*)
|
|
<span class="hljs-number">1</span>
|
|
|
|
* *stack*
|
|
NIL
|
|
</code></pre>
|
|
<p>Calling <code>pop</code> on an empty list has no effect.</p>
|
|
<pre><code class="lang-lisp">* *stack*
|
|
NIL
|
|
|
|
* (<span class="hljs-name">pop</span> *stack*)
|
|
NIL
|
|
|
|
* *stack*
|
|
NIL
|
|
</code></pre>
|
|
<h3 id="exercise-1412">Exercise 1.4.12</h3>
|
|
<p><strong>More Push and Pop</strong></p>
|
|
<p>Like <code>cons</code>, <code>push</code> isn't limited to the existing type of its target.</p>
|
|
<pre><code class="lang-lisp">* *stack*
|
|
NIL
|
|
|
|
* (<span class="hljs-name">push</span> <span class="hljs-number">1</span> *stack*)
|
|
(<span class="hljs-number">1</span>)
|
|
|
|
* (<span class="hljs-name">push</span> <span class="hljs-string">"b"</span> *stack*)
|
|
(<span class="hljs-string">"b"</span> <span class="hljs-number">1</span>)
|
|
|
|
* (<span class="hljs-name">push</span> 'c *stack*)
|
|
(<span class="hljs-name">c</span> <span class="hljs-string">"b"</span> <span class="hljs-number">1</span>)
|
|
|
|
* (<span class="hljs-name">push</span> (<span class="hljs-name">list</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span>) *stack*)
|
|
((<span class="hljs-number">4</span> <span class="hljs-number">5</span>) C <span class="hljs-string">"a"</span> <span class="hljs-number">1</span>)
|
|
|
|
* *stack*
|
|
((<span class="hljs-number">4</span> <span class="hljs-number">5</span>) C <span class="hljs-string">"a"</span> <span class="hljs-number">1</span>)
|
|
</code></pre>
|
|
<h3 id="exercise-1413">Exercise 1.4.13</h3>
|
|
<p><strong>First, Rest, and Last</strong></p>
|
|
<p>In addition to <code>car</code> and <code>cdr</code>, it's also possible to manipulate Cons-Cells using the <code>first</code> and <code>rest</code> functions. They're just different names for the same functions. <code>first</code> is the same as <code>car</code></p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">cons</span> 'a 'b)
|
|
(<span class="hljs-name">A</span> . B)
|
|
|
|
* (<span class="hljs-name">car</span> (<span class="hljs-name">cons</span> 'a 'b))
|
|
A
|
|
|
|
* (<span class="hljs-name">first</span> (<span class="hljs-name">cons</span> 'a 'b))
|
|
A
|
|
</code></pre>
|
|
<p>and <code>rest</code> is the same as <code>cdr</code></p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">cons</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span>)
|
|
(<span class="hljs-number">1</span> . <span class="hljs-number">2</span>)
|
|
|
|
* (<span class="hljs-name">cdr</span> (<span class="hljs-name">cons</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span>))
|
|
<span class="hljs-number">2</span>
|
|
|
|
* (<span class="hljs-name">rest</span> (<span class="hljs-name">cons</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span>))
|
|
<span class="hljs-number">2</span>
|
|
</code></pre>
|
|
<p>A third function, <code>last</code>, lets you get at the last Cons-Cell in a particular series.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">last</span> (<span class="hljs-name">cons</span> <span class="hljs-number">1</span> (<span class="hljs-name">cons</span> <span class="hljs-number">2</span> (<span class="hljs-name">cons</span> <span class="hljs-number">3</span> <span class="hljs-literal">nil</span>))))
|
|
(<span class="hljs-number">3</span>)
|
|
|
|
* (<span class="hljs-name">last</span> (<span class="hljs-name">cons</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span>))
|
|
(<span class="hljs-number">1</span> . <span class="hljs-number">2</span>)
|
|
|
|
* (<span class="hljs-name">last</span> (<span class="hljs-name">list</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span>))
|
|
(<span class="hljs-number">5</span>)
|
|
</code></pre>
|
|
<h3 id="exercise-1414">Exercise 1.4.14</h3>
|
|
<p><strong>List Position</strong></p>
|
|
<p>When dealing with linked lists, if you want to get at a particular element somewhere in the middle, you could either chain some <code>car</code>s and <code>cdr</code>s.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">car</span> (<span class="hljs-name">cdr</span> (<span class="hljs-name">cdr</span> (<span class="hljs-name">cdr</span> (<span class="hljs-name">list</span> <span class="hljs-number">0</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span>)))))
|
|
<span class="hljs-number">3</span>
|
|
|
|
* (<span class="hljs-name">cadddr</span> (<span class="hljs-name">list</span> <span class="hljs-number">0</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span>))
|
|
<span class="hljs-number">3</span>
|
|
</code></pre>
|
|
<p>or you could use the <code>nth</code> function.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">nth</span> <span class="hljs-number">3</span> (<span class="hljs-name">list</span> <span class="hljs-number">0</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span>))
|
|
<span class="hljs-number">3</span>
|
|
|
|
* (<span class="hljs-name">nth</span> <span class="hljs-number">4</span> (<span class="hljs-name">list</span> <span class="hljs-number">0</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span>))
|
|
<span class="hljs-number">4</span>
|
|
|
|
* (<span class="hljs-name">nth</span> <span class="hljs-number">5</span> (<span class="hljs-name">list</span> <span class="hljs-number">5</span> <span class="hljs-number">4</span> <span class="hljs-number">3</span> <span class="hljs-number">2</span> <span class="hljs-number">1</span> <span class="hljs-number">0</span>))
|
|
<span class="hljs-number">0</span>
|
|
</code></pre>
|
|
<p>This isn't any more efficient (in the run-time sense) than <code>cdr</code> traversal, but is shorter to write if you need to access some deeper list element in a flat list.</p>
|
|
<h3 id="exercise-1415">Exercise 1.4.15</h3>
|
|
<p><strong>Appending</strong></p>
|
|
<p>Putting lists together is the job of the <code>append</code> function.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">append</span> (<span class="hljs-name">list</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span>) (<span class="hljs-name">list</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span> <span class="hljs-number">6</span>))
|
|
(<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span> <span class="hljs-number">6</span>)
|
|
|
|
* (<span class="hljs-name">append</span> (<span class="hljs-name">list</span> <span class="hljs-number">6</span> <span class="hljs-number">5</span> <span class="hljs-number">4</span> <span class="hljs-number">3</span>) (<span class="hljs-name">list</span> <span class="hljs-number">2</span> <span class="hljs-number">1</span>))
|
|
(<span class="hljs-number">6</span> <span class="hljs-number">5</span> <span class="hljs-number">4</span> <span class="hljs-number">3</span> <span class="hljs-number">2</span> <span class="hljs-number">1</span>)
|
|
</code></pre>
|
|
<p><code>append</code> is an example of a function that takes a <code>&rest</code> argument. Meaning you can pass it any number of lists...</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">append</span> (<span class="hljs-name">list</span> 'a 'b 'c 'd) (<span class="hljs-name">list</span> 'e 'f) (<span class="hljs-name">list</span> 'g))
|
|
(<span class="hljs-name">A</span> B C D E F G)
|
|
|
|
* (<span class="hljs-name">append</span> (<span class="hljs-name">list</span> <span class="hljs-number">1</span>) (<span class="hljs-name">list</span> <span class="hljs-number">2</span>) (<span class="hljs-name">list</span> <span class="hljs-number">3</span>) (<span class="hljs-name">list</span> <span class="hljs-number">4</span>))
|
|
(<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span>)
|
|
</code></pre>
|
|
<p>...though passing it one list is pointless.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">append</span> (<span class="hljs-name">list</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span>))
|
|
(<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span>)
|
|
|
|
* (<span class="hljs-name">list</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span>)
|
|
(<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span>)
|
|
</code></pre>
|
|
<h3 id="exercise-1416">Exercise 1.4.16</h3>
|
|
<p><strong>More Appending</strong></p>
|
|
<p>Like <code>car</code>, <code>cdr</code>, <code>first</code>, <code>rest</code>, <code>last</code> and <code>nth</code>, <code>append</code> is functional. It will return a new list rather than mutating any of its arguments.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">defvar</span> *lst* (<span class="hljs-name">list</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span>))
|
|
*lst*
|
|
|
|
* *lst*
|
|
(<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span>)
|
|
|
|
* (<span class="hljs-name">append</span> *lst* (<span class="hljs-name">list</span> <span class="hljs-number">6</span> <span class="hljs-number">7</span> <span class="hljs-number">8</span>))
|
|
(<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span> <span class="hljs-number">6</span> <span class="hljs-number">7</span> <span class="hljs-number">8</span>)
|
|
|
|
* *lst*
|
|
(<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span>)
|
|
|
|
* (<span class="hljs-name">append</span> (<span class="hljs-name">list</span> <span class="hljs-number">-3</span> <span class="hljs-number">-2</span> <span class="hljs-number">-1</span> <span class="hljs-number">0</span>) *lst*)
|
|
(<span class="hljs-name">-3</span> <span class="hljs-number">-2</span> <span class="hljs-number">-1</span> <span class="hljs-number">0</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span>)
|
|
|
|
* *lst*
|
|
(<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span>)
|
|
|
|
* (<span class="hljs-name">append</span> (<span class="hljs-name">list</span> <span class="hljs-number">0</span>) *lst* (<span class="hljs-name">list</span> <span class="hljs-number">6</span>))
|
|
(<span class="hljs-number">0</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span> <span class="hljs-number">6</span>)
|
|
|
|
* *lst*
|
|
(<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span>)
|
|
</code></pre>
|
|
<p>This means both that you may safely pass it any data you want appended without worrying about losing the original lists, and that if you want such behavior, you need to explicitly assign the result of <code>append</code> yourself.</p>
|
|
<h3 id="exercise-1417">Exercise 1.4.17</h3>
|
|
<p><strong>Circular Lists</strong></p>
|
|
<p>The destructive equivalent of <code>append</code> is <code>nconc</code>. Using such side-effects, it's possible to create circular lists.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">defparameter</span> *cycle* (<span class="hljs-name">list</span> 'a 'b))
|
|
*CYCLE*
|
|
|
|
* (<span class="hljs-name">first</span> *cycle*)
|
|
A
|
|
|
|
* (<span class="hljs-name">second</span> *cycle*)
|
|
B
|
|
|
|
* (<span class="hljs-name">third</span> *cycle*)
|
|
NIL
|
|
|
|
* (<span class="hljs-name">fourth</span> *cycle*)
|
|
NIL
|
|
</code></pre>
|
|
<p>Before we create an actual cycle, we need to tell the interpreter to print them (otherwise the request to print a circular list would never return; unlike Haskell, Common Lisp is not a lazy language by default).</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">setf</span> *print-circle* <span class="hljs-literal">t</span>)
|
|
T
|
|
|
|
* (<span class="hljs-name">nconc</span> *cycle* *cycle*)
|
|
#1=(<span class="hljs-name">A</span> B . #1#)
|
|
|
|
* (<span class="hljs-name">third</span> *cycle*)
|
|
A
|
|
|
|
* (<span class="hljs-name">fourth</span> *cycle*)
|
|
B
|
|
|
|
* (<span class="hljs-name">loop</span> repeat <span class="hljs-number">15</span> for elem in *cycle* collect elem)
|
|
(<span class="hljs-name">A</span> B A B A B A B A B A B A B A)
|
|
</code></pre>
|
|
<h3 id="exercise-1418">Exercise 1.4.18</h3>
|
|
<p><strong>Circular Trees</strong></p>
|
|
<p>The <code>nconc</code> procedure is fine when all you want is a simple cycle, but it's also possible to use direct mutation to create more elaborate structures.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">defparameter</span> *knot* (<span class="hljs-name">list</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> (<span class="hljs-name">cons</span> <span class="hljs-literal">nil</span> <span class="hljs-literal">nil</span>)))
|
|
*KNOT*
|
|
|
|
* (<span class="hljs-name">setf</span> (<span class="hljs-name">car</span> (<span class="hljs-name">nth</span> <span class="hljs-number">4</span> *knot*)) (<span class="hljs-name">cdr</span> *knot*))
|
|
#1=(<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> (<span class="hljs-name">#1#</span>))
|
|
|
|
* (<span class="hljs-name">setf</span> (<span class="hljs-name">cdr</span> (<span class="hljs-name">nth</span> <span class="hljs-number">4</span> *knot*)) (<span class="hljs-name">cddr</span> *knot*))
|
|
#1=(<span class="hljs-number">3</span> <span class="hljs-number">4</span> ((<span class="hljs-number">1</span> <span class="hljs-number">2</span> . #1#) . #1#))
|
|
</code></pre>
|
|
<p>Now we've got a structure that branches back on itself twice.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">defun</span> cycle-walk (<span class="hljs-name">count</span> cycle <span class="hljs-symbol">&key</span> (<span class="hljs-name">turn</span> #'car))
|
|
(<span class="hljs-name">loop</span> with place = cycle
|
|
repeat count for elem = (<span class="hljs-name">car</span> place)
|
|
unless (<span class="hljs-name">consp</span> elem) do (<span class="hljs-name">format</span> <span class="hljs-literal">t</span> <span class="hljs-string">"~a "</span> elem)
|
|
do (<span class="hljs-name">setf</span> place (<span class="hljs-name">if</span> (<span class="hljs-name">consp</span> elem)
|
|
(<span class="hljs-name">funcall</span> turn elem)
|
|
(<span class="hljs-name">cdr</span> place)))))
|
|
CYCLE-WALK
|
|
|
|
* (<span class="hljs-name">cycle-walk</span> <span class="hljs-number">25</span> *knot* <span class="hljs-symbol">:turn</span> #'car)
|
|
<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span>
|
|
NIL
|
|
|
|
* (<span class="hljs-name">cycle-walk</span> <span class="hljs-number">25</span> *knot* <span class="hljs-symbol">:turn</span> #'cdr)
|
|
<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span>
|
|
NIL
|
|
|
|
* (<span class="hljs-name">let</span> ((<span class="hljs-name">dir</span>))
|
|
(<span class="hljs-name">defun</span> switch (<span class="hljs-name">pair</span>)
|
|
(<span class="hljs-name">setf</span> dir (<span class="hljs-name">not</span> dir))
|
|
(<span class="hljs-name">if</span> dir
|
|
(<span class="hljs-name">car</span> pair)
|
|
(<span class="hljs-name">cdr</span> pair))))
|
|
SWITCH
|
|
|
|
* (<span class="hljs-name">cycle-walk</span> <span class="hljs-number">25</span> *knot* <span class="hljs-symbol">:turn</span> #'switch)
|
|
<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span>
|
|
NIL
|
|
</code></pre>
|
|
<p>Of course, it's possible to go further. Large, divergent "trees" that eventually cycle backwards from any number of branches at arbitrary depths. You'd build them the same way though; using some combination of <code>nconc</code>, <code>setf</code> along with <code>car</code>/<code>cdr</code> and friends.</p>
|
|
<h3 id="exercise-1419">Exercise 1.4.19</h3>
|
|
<p><strong>Quoting</strong></p>
|
|
<p>Another way to construct tree structure is using the <code>quote</code> or <code>'</code>.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">quote</span> (<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span>))
|
|
(<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span>)
|
|
|
|
* '(<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span>)
|
|
(<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span>)
|
|
|
|
* (<span class="hljs-name">list</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span>)
|
|
(<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span>)
|
|
</code></pre>
|
|
<p>The structures you create this way are equivalent.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">equal</span> (<span class="hljs-name">quote</span> (<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span>)) '(<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span>))
|
|
T
|
|
|
|
* (<span class="hljs-name">equal</span> '(<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span>) (<span class="hljs-name">list</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span>))
|
|
T
|
|
</code></pre>
|
|
<p>The difference is that, while <code>list</code> essentially means "Return the list of these arguments", <code>quote</code>/<code>'</code> means "Return this argument without evaluating it".</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">defparameter</span> *test* <span class="hljs-number">2</span>)
|
|
*test*
|
|
|
|
* (<span class="hljs-name">list</span> <span class="hljs-number">1</span> *test* <span class="hljs-number">3</span>)
|
|
(<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span>)
|
|
|
|
* '(<span class="hljs-number">1</span> *test* <span class="hljs-number">3</span>)
|
|
(<span class="hljs-number">1</span> *test* <span class="hljs-number">3</span>)
|
|
|
|
* (<span class="hljs-name">list</span> (<span class="hljs-name">+</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span>) (<span class="hljs-name">+</span> <span class="hljs-number">5</span> <span class="hljs-number">6</span>) (<span class="hljs-name">+</span> <span class="hljs-number">7</span> <span class="hljs-number">8</span>))
|
|
(<span class="hljs-number">7</span> <span class="hljs-number">11</span> <span class="hljs-number">15</span>)
|
|
|
|
* '((+ <span class="hljs-number">3</span> <span class="hljs-number">4</span>) (+ <span class="hljs-number">5</span> <span class="hljs-number">6</span>) (+ <span class="hljs-number">7</span> <span class="hljs-number">8</span>))
|
|
((<span class="hljs-name">+</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span>) (<span class="hljs-name">+</span> <span class="hljs-number">5</span> <span class="hljs-number">6</span>) (<span class="hljs-name">+</span> <span class="hljs-number">7</span> <span class="hljs-number">8</span>))
|
|
</code></pre>
|
|
<h3 id="exercise-1420">Exercise 1.4.20</h3>
|
|
<p><strong>More Quoting</strong></p>
|
|
<p>Because <code>quote</code> supresses evaluation, you can use it to more easily build deeply nested structures.</p>
|
|
<pre><code class="lang-lisp">* (<span class="hljs-name">list</span> <span class="hljs-number">1</span> (<span class="hljs-name">list</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span>) (<span class="hljs-name">list</span> <span class="hljs-number">4</span> (<span class="hljs-name">list</span> (<span class="hljs-name">list</span> <span class="hljs-number">5</span>) <span class="hljs-number">6</span> <span class="hljs-number">7</span> <span class="hljs-number">8</span>)))
|
|
(<span class="hljs-number">1</span> (<span class="hljs-number">2</span> <span class="hljs-number">3</span>) (<span class="hljs-number">4</span> ((<span class="hljs-number">5</span>) <span class="hljs-number">6</span> <span class="hljs-number">7</span> <span class="hljs-number">8</span>)))
|
|
|
|
* '(<span class="hljs-number">1</span> (<span class="hljs-number">2</span> <span class="hljs-number">3</span>) (<span class="hljs-number">4</span> ((<span class="hljs-number">5</span>) <span class="hljs-number">6</span> <span class="hljs-number">7</span> <span class="hljs-number">8</span>)))
|
|
(<span class="hljs-number">1</span> (<span class="hljs-number">2</span> <span class="hljs-number">3</span>) (<span class="hljs-number">4</span> ((<span class="hljs-number">5</span>) <span class="hljs-number">6</span> <span class="hljs-number">7</span> <span class="hljs-number">8</span>)))
|
|
</code></pre>
|
|
<p>Take care not to use quoted data for mutation though. While the structures produced may be the same, mutating a quoted structure is undefined by the Common Lisp language spec, and is thus entirely implementation dependant.</p>
|
|
<pre><code class="lang-lisp">* (defvar *listed* (list 3 2 1))
|
|
*listed*
|
|
|
|
* (defvar *quoted* '(3 2 1))
|
|
*quoted*
|
|
|
|
* (push 4 *listed*)
|
|
(4 3 2 1)
|
|
|
|
* *listed*
|
|
(4 3 2 1)
|
|
|
|
* (push 4 *quoted*)
|
|
???
|
|
|
|
* *quoted*
|
|
???
|
|
</code></pre>
|
|
<p>The question marks aren't there so you can figure out what the results are supposed to be. They signify that what you get back in these situations depends on which implementation of Common Lisp you're using. They may do incompatible things, but because the spec leaves this situation undefined, none of them are actually wrong. So, you know ... careful.</p>
|
|
|
|
|
|
</section>
|
|
|
|
</div>
|
|
<div class="search-results">
|
|
<div class="has-results">
|
|
|
|
<h1 class="search-results-title"><span class='search-results-count'></span> results matching "<span class='search-query'></span>"</h1>
|
|
<ul class="search-results-list"></ul>
|
|
|
|
</div>
|
|
<div class="no-results">
|
|
|
|
<h1 class="search-results-title">No results matching "<span class='search-query'></span>"</h1>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<a href="1-03-0-getting-input-from-users.html" class="navigation navigation-prev " aria-label="Previous page: Extra Credit: Getting Input from Users">
|
|
<i class="fa fa-angle-left"></i>
|
|
</a>
|
|
|
|
|
|
<a href="1-05-0-lookups-trees.html" class="navigation navigation-next " aria-label="Next page: Extra Credit: Look-up Lists and Trees">
|
|
<i class="fa fa-angle-right"></i>
|
|
</a>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
<script>
|
|
var gitbook = gitbook || [];
|
|
gitbook.push(function() {
|
|
gitbook.page.hasChanged({"page":{"title":"Lists and List-Operations","level":"3.1.4","depth":2,"next":{"title":"Extra Credit: Look-up Lists and Trees","level":"3.1.5","depth":2,"path":"1-05-0-lookups-trees.md","ref":"./1-05-0-lookups-trees.md","articles":[]},"previous":{"title":"Extra Credit: Getting Input from Users","level":"3.1.3","depth":2,"path":"1-03-0-getting-input-from-users.md","ref":"./1-03-0-getting-input-from-users.md","articles":[]},"dir":"ltr"},"config":{"plugins":["hints","folding-chapters"],"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"pluginsConfig":{"hints":{"danger":"fa fa-exclamation-circle","info":"fa fa-info-circle","tip":"fa fa-mortar-board","working":"fa fa-wrench"},"folding-chapters":{},"highlight":{},"search":{},"lunr":{"maxIndexSize":1000000,"ignoreSpecialCharacters":false},"sharing":{"facebook":true,"twitter":true,"google":false,"weibo":false,"instapaper":false,"vk":false,"all":["facebook","google","twitter","weibo","instapaper"]},"fontsettings":{"theme":"white","family":"sans","size":2},"theme-default":{"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"showLevel":false}},"theme":"default","author":"\"the Phoeron\" Colin J.E. Lupton","pdf":{"pageNumbers":true,"fontSize":12,"fontFamily":"Arial","paperSize":"a4","chapterMark":"pagebreak","pageBreaksBefore":"/","margin":{"right":62,"left":62,"top":56,"bottom":56}},"structure":{"langs":"LANGS.md","readme":"index.md","glossary":"GLOSSARY.md","summary":"SUMMARY.md"},"variables":{},"title":"Learn Lisp The Hard Way","gitbook":"*"},"file":{"path":"1-04-0-lists.md","mtime":"2022-08-22T22:47:49.767Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2022-08-24T16:15:01.957Z"},"basePath":".","book":{"language":""}});
|
|
});
|
|
</script>
|
|
</div>
|
|
|
|
|
|
<script src="gitbook/gitbook.js"></script>
|
|
<script src="gitbook/theme.js"></script>
|
|
|
|
|
|
<script src="gitbook/gitbook-plugin-folding-chapters/folding-chapters.js"></script>
|
|
|
|
|
|
|
|
<script src="gitbook/gitbook-plugin-search/search-engine.js"></script>
|
|
|
|
|
|
|
|
<script src="gitbook/gitbook-plugin-search/search.js"></script>
|
|
|
|
|
|
|
|
<script src="gitbook/gitbook-plugin-lunr/lunr.min.js"></script>
|
|
|
|
|
|
|
|
<script src="gitbook/gitbook-plugin-lunr/search-lunr.js"></script>
|
|
|
|
|
|
|
|
<script src="gitbook/gitbook-plugin-sharing/buttons.js"></script>
|
|
|
|
|
|
|
|
<script src="gitbook/gitbook-plugin-fontsettings/fontsettings.js"></script>
|
|
|
|
|
|
|
|
</body>
|
|
</html>
|
|
|