www.it-ebooks.info
www.it-ebooks.info
Clojure Programming
Chas Emerick, Brian Carper, and Christophe Grand
Beijing • Cambridge • Farnham • Köln • Sebastopol • Tokyo
www.it-ebooks.info
Clojure Programming
by Chas Emerick, Brian Carper, and Christophe Grand
Copyright © 2012 Chas Emerick, Brian Carper, and Christophe Grand. All rights reserved.
Printed in the United States of America.
Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472.
O’Reilly books may be purchased for educational, business, or sales promotional use. Online editions
are also available for most titles (http://my.safaribooksonline.com). For more information, contact our
corporate/institutional sales department: (800) 998-9938 or
[email protected].
Editors: Mike Loukides and Julie Steele
Production Editor: Teresa Elsey
Copyeditor: Nancy Reinhardt
Proofreader: Linley Dolby
April 2012:
Indexer: Fred Brown
Cover Designer: Karen Montgomery
Interior Designer: David Futato
Illustrator: Robert Romano
First Edition.
Revision History for the First Edition:
2012-03-28
First release
See http://oreilly.com/catalog/errata.csp?isbn=9781449394707 for release details.
Nutshell Handbook, the Nutshell Handbook logo, and the O’Reilly logo are registered trademarks of
O’Reilly Media, Inc. Clojure Programming, the image of a painted snipe, and related trade dress are
trademarks of O’Reilly Media, Inc.
Many of the designations used by manufacturers and sellers to distinguish their products are claimed as
trademarks. Where those designations appear in this book, and O’Reilly Media, Inc., was aware of a
trademark claim, the designations have been printed in caps or initial caps.
While every precaution has been taken in the preparation of this book, the publisher and authors assume
no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.
ISBN: 978-1-449-39470-7
[LSI]
1332955528
www.it-ebooks.info
Table of Contents
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
1. Down the Rabbit Hole . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Why Clojure?
Obtaining Clojure
The Clojure REPL
No, Parentheses Actually Won’t Make You Go Blind
Expressions, Operators, Syntax, and Precedence
Homoiconicity
The Reader
Scalar Literals
Comments
Whitespace and Commas
Collection Literals
Miscellaneous Reader Sugar
Namespaces
Symbol Evaluation
Special Forms
Suppressing Evaluation: quote
Code Blocks: do
Defining Vars: def
Local Bindings: let
Destructuring (let, Part 2)
Creating Functions: fn
Conditionals: if
Looping: loop and recur
Referring to Vars: var
Java Interop: . and new
Exception Handling: try and throw
Specialized Mutation: set!
Primitive Locking: monitor-enter and monitor-exit
Putting It All Together
1
3
3
6
7
9
12
13
18
19
19
20
20
23
23
24
25
26
27
28
36
42
43
44
44
45
45
45
46
iii
www.it-ebooks.info
eval
This Is Just the Beginning
46
48
Part I. Functional Programming and Concurrency
2. Functional Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
What Does Functional Programming Mean?
On the Importance of Values
About Values
Comparing Values to Mutable Objects
A Critical Choice
First-Class and Higher-Order Functions
Applying Ourselves Partially
Composition of Function(ality)
Writing Higher-Order Functions
Building a Primitive Logging System with Composable Higher-Order
Functions
Pure Functions
Why Are Pure Functions Interesting?
Functional Programming in the Real World
52
52
53
54
58
59
65
68
71
72
76
78
81
3. Collections and Data Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Abstractions over Implementations
Collection
Sequences
Associative
Indexed
Stack
Set
Sorted
Concise Collection Access
Idiomatic Usage
Collections and Keys and Higher-Order Functions
Data Structure Types
Lists
Vectors
Sets
Maps
Immutability and Persistence
Persistence and Structural Sharing
Transients
Metadata
iv | Table of Contents
www.it-ebooks.info
84
87
89
99
103
104
105
106
111
112
113
114
114
115
117
117
122
123
130
134
Putting Clojure’s Collections to Work
Identifiers and Cycles
Thinking Different: From Imperative to Functional
Navigation, Update, and Zippers
In Summary
136
137
138
151
157
4. Concurrency and Parallelism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
Shifting Computation Through Time and Space
Delays
Futures
Promises
Parallelism on the Cheap
State and Identity
Clojure Reference Types
Classifying Concurrent Operations
Atoms
Notifications and Constraints
Watches
Validators
Refs
Software Transactional Memory
The Mechanics of Ref Change
The Sharp Corners of Software Transactional Memory
Vars
Defining Vars
Dynamic Scope
Vars Are Not Variables
Forward Declarations
Agents
Dealing with Errors in Agent Actions
I/O, Transactions, and Nested Sends
Using Java’s Concurrency Primitives
Locking
Final Thoughts
160
160
162
163
166
168
170
172
174
176
176
178
180
180
181
191
198
198
201
206
208
209
212
214
224
225
226
Part II. Building Abstractions
5. Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
What Is a Macro?
What Macros Are Not
What Can Macros Do that Functions Cannot?
Macros Versus Ruby eval
229
231
232
234
Table of Contents | v
www.it-ebooks.info
Writing Your First Macro
Debugging Macros
Macroexpansion
Syntax
quote Versus syntax-quote
unquote and unquote-splicing
When to Use Macros
Hygiene
Gensyms to the Rescue
Letting the User Pick Names
Double Evaluation
Common Macro Idioms and Patterns
The Implicit Arguments: &env and &form
&env
&form
Testing Contextual Macros
In Detail: -> and ->>
Final Thoughts
235
237
237
239
240
241
243
244
246
248
249
250
251
252
254
258
259
262
6. Datatypes and Protocols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
Protocols
Extending to Existing Types
Defining Your Own Types
Records
Types
Implementing Protocols
Inline Implementation
Reusing Implementations
Protocol Introspection
Protocol Dispatch Edge Cases
Participating in Clojure’s Collection Abstractions
Final Thoughts
264
266
270
272
277
280
281
285
289
290
292
299
7. Multimethods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
Multimethods Basics
Toward Hierarchies
Hierarchies
Independent Hierarchies
Making It Really Multiple!
A Few More Things
Multiple Inheritance
Introspecting Multimethods
type Versus class; or, the Revenge of the Map
vi | Table of Contents
www.it-ebooks.info
301
304
306
308
311
313
313
314
314
The Range of Dispatch Functions Is Unlimited
Final Thoughts
316
317
Part III. Tools, Platform, and Projects
8. Organizing and Building Clojure Projects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
Project Geography
Defining and Using Namespaces
Location, Location, Location
The Functional Organization of Clojure Codebases
Build
Ahead-of-Time Compilation
Dependency Management
The Maven Dependency Management Model
Build Tools and Configuration Patterns
Final Thoughts
321
322
332
334
336
337
339
339
344
353
9. Java and JVM Interoperability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355
The JVM Is Clojure’s Foundation
Using Java Classes, Methods, and Fields
Handy Interop Utilities
Exceptions and Error Handling
Escaping Checked Exceptions
with-open, finally’s Lament
Type Hinting for Performance
Arrays
Defining Classes and Implementing Interfaces
Instances of Anonymous Classes: proxy
Defining Named Classes
Annotations
Using Clojure from Java
Using deftype and defrecord Classes
Implementing Protocol Interfaces
Collaborating Partners
356
357
360
362
364
364
366
370
371
372
374
381
385
388
390
392
10. REPL-Oriented Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393
Interactive Development
The Persistent, Evolving Environment
Tooling
The Bare REPL
Eclipse
Emacs
393
397
398
399
403
405
Table of Contents | vii
www.it-ebooks.info
Debugging, Monitoring, and Patching Production in the REPL
Special Considerations for “Deployed” REPLs
Limitations to Redefining Constructs
In Summary
411
414
415
417
Part IV. Practicums
11. Numerics and Mathematics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421
Clojure Numerics
Clojure Prefers 64-bit (or Larger) Representations
Clojure Has a Mixed Numerics Model
Rationals
The Rules of Numeric Contagion
Clojure Mathematics
Bounded Versus Arbitrary Precision
Unchecked Ops
Scale and Rounding Modes for Arbitrary-Precision Decimals Ops
Equality and Equivalence
Object Identity (identical?)
Reference Equality (=)
Numeric Equivalence (==)
Optimizing Numeric Performance
Declare Functions to Take and Return Primitives
Use Primitive Arrays Judiciously
Visualizing the Mandelbrot Set in Clojure
421
422
422
424
425
427
428
430
432
433
433
434
435
436
438
442
449
12. Design Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 457
Dependency Injection
Strategy Pattern
Chain of Responsibility
Aspect-Oriented Programming
Final Thoughts
459
462
463
466
470
13. Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471
Immutable Values and Pure Functions
Mocking
clojure.test
Defining Tests
Test “Suites”
Fixtures
Growing an HTML DSL
Relying upon Assertions
viii | Table of Contents
www.it-ebooks.info
471
472
473
474
477
479
481
486
Preconditions and Postconditions
487
14. Using Relational Databases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 491
clojure.java.jdbc
with-query-results Explained
Transactions
Connection Pooling
Korma
Prelude
Queries
Why Bother with a DSL?
Hibernate
Setup
Persisting Data
Running Queries
Removing Boilerplate
Final Thoughts
491
494
496
496
498
498
499
500
503
503
506
506
507
509
15. Using Nonrelational Databases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 511
Getting Set Up with CouchDB and Clutch
Basic CRUD Operations
Views
A Simple (JavaScript) View
Views in Clojure
_changes: Abusing CouchDB as a Message Queue
À la Carte Message Queues
Final Thoughts
512
512
514
514
516
520
522
525
16. Clojure and the Web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 527
The “Clojure Stack”
The Foundation: Ring
Requests and Responses
Adapters
Handlers
Middleware
Routing Requests with Compojure
Templating
Enlive: Selector-Based HTML Transformation
Final Thoughts
527
529
529
531
532
534
535
545
546
554
17. Deploying Clojure Web Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 557
Java and Clojure Web Architecture
Web Application Packaging
557
560
Table of Contents | ix
www.it-ebooks.info
Running Web Apps Locally
Web Application Deployment
Deploying Clojure Apps to Amazon’s Elastic Beanstalk
Going Beyond Simple Web Application Deployment
565
566
567
570
Part V. Miscellanea
18. Choosing Clojure Type Definition Forms Wisely . . . . . . . . . . . . . . . . . . . . . . . . . . . . 573
19. Introducing Clojure into Your Workplace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 577
Just the Facts…
Emphasize Productivity
Emphasize Community
Be Prudent
577
579
580
582
20. What’s Next? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583
(dissoc Clojure 'JVM)
ClojureCLR
ClojureScript
4Clojure
Overtone
core.logic
Pallet
Avout
Clojure on Heroku
583
583
584
584
585
585
586
587
587
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 589
x | Table of Contents
www.it-ebooks.info
Preface
Clojure is a dynamically and strongly typed programming language hosted on the Java
Virtual Machine (JVM), now in its fifth year. It has seen enthusiastic adoption by programmers from a variety of backgrounds, working in essentially all problem domains.
Clojure offers a compelling mix of features and characteristics applicable to solving
modern programming challenges:
• Functional programming foundations, including a suite of persistent data structures with performance characteristics approaching typical mutable data structures
• A mature, efficient runtime environment, as provided by the host JVM
• JVM/Java interoperability capabilities suited for a wide variety of architectural and
operational requirements
• A set of mechanisms providing reliable concurrency and parallelism semantics
• A Lisp pedigree, thereby providing remarkably flexible and powerful metaprogramming facilities
Clojure offers a compelling practical alternative to many who strain against the limitations of typical programming languages and environments. We aim to demonstrate
this by showing Clojure seamlessly interoperating with existing technologies, libraries,
and services that many working programmers already use on a day-to-day basis.
Throughout, we’ll provide a solid grounding in Clojure fundamentals, starting from
places of common expertise and familiarity rather than from (often foreign) computer
science first principles.
Who Is This Book For?
We wrote this book with a couple of audiences in mind. Hopefully, you consider yourself a part of one of them.
Clojure matches and often exceeds your current favorite language’s expressivity, concision, and flexibility while allowing you to effortlessly leverage the performance, libraries, community, and operational stability of the JVM. This makes it a natural next
step for Java developers (and even JVM developers using interpreted or otherwise not
xi
www.it-ebooks.info
particularly fast non-Java languages), who simply will not accept a performance hit or
who do not want to give up their JVM platform investment. Clojure is also a natural
step for Ruby and Python developers who refuse to compromise on language expressivity, but wish they had a more reliable, efficient execution platform and a larger selection of quality libraries.
Engaged Java Developers
There are millions of Java developers in the world, but some fewer number are working
in demanding environments solving nontrivial, often domain-specific problems. If this
describes you, you’re probably always on the hunt for better tools, techniques, and
practices that will boost your productivity and value to your team, organization, and
community. In addition, you’re probably at least somewhat frustrated with the constraints of Java compared to other languages, but you continue to find the JVM ecosystem compelling: its process maturity, massive third-party library selection, vendor
support, and large skilled workforce is hard to walk away from, no matter how shiny
and appealing alternative languages are.
You’ll find Clojure to be a welcome relief. It runs on the JVM with excellent performance characteristics, interoperates with all of your existing libraries, tools, and applications, and is simpler than Java, yet is demonstrably more expressive and less
verbose.
Ruby, Python, and Other Developers
Ruby and Python are not new languages by any means, but they have garnered significant (dare we say, “mainstream”?) traction over recent years. It’s not hard to see why:
both are expressive, dynamic languages that, along with their thriving communities,
encourage maximal developer productivity in many domains.
Clojure is a natural next step for you. As a Ruby or Python programmer, you’re probably
unwilling to compromise on their strengths, but you may wish for a more capable
execution platform, better runtime performance, and a larger selection of libraries. The
fact that Clojure is efficiently hosted on the JVM fulfills those desires—and it matches
or exceeds the degrees of language sophistication and developer productivity that
you’ve come to expect.
We will frequently compare and contrast Clojure with Java, Ruby, and
Python to help you translate your existing expertise to Clojure. In such
comparisons, we will always refer to the canonical implementations of
these other languages:
• Ruby MRI (also called CRuby)
• CPython
• Java 6/7
xii | Preface
www.it-ebooks.info
How to Read This Book
In formulating our approach to this book, we wanted to provide a fair bit of concrete
detail and practical examples that you could relate to, but stay clear of what we thought
were generally unsuccessful approaches for doing so. In particular, we’ve been frustrated in the past by books that attempted to thread the implementation of a single
program or application through their pages. Such approaches seem to result in a disjointed narrative, as well as the dominance of a tortured “practical” example that may
or may not apply or appeal to readers.
With that in mind, we split the book in two, starting with foundational, instructional
narrative that occupies roughly two-thirds of the book, followed in Part IV by a number
of discrete, practical examples from real-world domains. This clear segmentation of
content with decidedly distinct objectives may qualify this book as a “duplex book.”
(This term may have been coined by Martin Fowler in http://martinfowler.com/bliki/
DuplexBook.html.) In any case, we can conceive of two obvious approaches to
reading it.
Start with Practical Applications of Clojure
Often the best way to learn is to dig straight into the nitty-gritty of how a language is
used in the real world. If that sounds appealing, the hope is that you will find that at
least a couple of the practicums resonate with what you do on a day-to-day basis, so
that you can readily draw parallels between how you solve certain categories of problems in your current language(s) and how they may be solved using Clojure. You’re
going to bump into a lot of potentially foreign concepts and language constructs in
those chapters—when you do, use that context within the domain in question as your
entry point for understanding those concepts using the relevant instructional material
in the first part of the book.
Start from the Ground Up with Clojure’s Foundational Concepts
Sometimes the only way to truly understand something is to learn it inside-out, starting
with the fundamentals. If you prefer that approach, then you will likely find that digesting this book starting from the first page of Chapter 1 will be best. We have attempted to provide a comprehensive treatment of all of Clojure’s foundational principles and constructs in a narrative that progresses such that it will be very rare for you
to need to look ahead in the book to understand concepts in earlier sections. As you
begin to get a handle on Clojure’s fundamentals, feel free to jump ahead into the practicums you find most interesting and relevant to your work.
Preface | xiii
www.it-ebooks.info
Who’s “We”?
We are three software developers who have each taken different paths in coming to use
and appreciate Clojure. In writing this book, we have attempted to distill all that we’ve
learned about why and how you should use Clojure so that you can be successful in
your use of it as well.
Chas Emerick
Chas has been a consistent presence in the Clojure community since early 2008. He
has made contributions to the core language, been involved in dozens of Clojure open
source projects, and frequently writes and speaks about Clojure and software development generally.
Chas maintains the Clojure Atlas (http://clojureatlas.com), an interactive visualization
of and learning aid for the Clojure language and its standard libraries.
The founder of Snowtide (http://snowtide.com), a small software company in Western
Massachusetts, Chas’s primary domain is unstructured data extraction, with a particular specialty around PDF documents. He writes about Clojure, software development,
entrepreneurship, and other passions at http://cemerick.com.
Brian Carper
Brian is a Ruby programmer turned Clojure devotee. He’s been programming Clojure
since 2008, using it at home and at work for everything from web development to data
analysis to GUI apps.
Brian is the author of Gaka (https://github.com/briancarper/gaka), a Clojure-to-CSS
compiler, and Oyako (https://github.com/briancarper/oyako), an Object-Relational
Mapping library. He writes about Clojure and other topics at http://briancarper.net.
Christophe Grand
Christophe was a long-time enthusiast of functional programming lost in Java-land
when he encountered Clojure in early 2008, and it was love at first sight! He authored
Enlive (http://github.com/cgrand/enlive), an HTML/XML transformation, extraction,
and templating library; Parsley (http://github.com/cgrand/parsley), an incremental
parser generator; and Moustache (http://github.com/cgrand/moustache), a routing and
middleware application DSL for Ring.
As an independent consultant, he develops, coaches, and offers training in Clojure. He
also writes about Clojure at http://clj-me.cgrand.net.
xiv | Preface
www.it-ebooks.info
Acknowledgments
Like any sizable piece of work, this book would not exist without the tireless efforts of
dozens, probably hundreds of people.
First, Rich Hickey, the creator of Clojure. In just a few short years, he has designed,
implemented, and shepherded a new programming language into the world that, for
so many, has been not just another tool, but a reinvigoration of our love of programming. Beyond that, he’s personally taught us a great deal—certainly about programming, but also about patience, humility, and perspective. Thanks, Rich.
Dave Fayram and Mike Loukides were essential in helping to formulate the initial concept and approach of the book. Of course, you likely wouldn’t be reading this book
right now if it weren’t for Julie Steele, our editor, and all of the fine people at O’Reilly
who took care of the logistics and minutiae that go along with publishing.
The quality of this book would be far less than it is were it not for the efforts of our
technical reviewers, including Sam Aaron, Antoni Batchelli, Tom Faulhaber, Chris
Granger, Anthony Grimes, Phil Hagelberg, Tom Hicks, Alex Miller, William Morgan,
Laurent Petit, and Dean Wampler. We’d also like to thank all of those who provided
feedback and comments on the early releases and Rough Cuts of the book, both on the
O’Reilly forums and via email, Twitter, and so on.
Michael Fogus and Chris Houser have inspired us in many ways large and small. One
of the smaller ways was the style and presentation of the REPL interactions in their
Clojure book, The Joy of Clojure, which we shamelessly copied and iterated.
If we’ve neglected to mention anyone, please accept our implicit thanks and our apologies; at the end of this endeavor, we are quite lucky to be upright and coherent at all!
And Last, but Certainly Far from Least
The Clojure community has been my home away from home for a number of years.
The hospitality and positive, helpful energy I see anywhere Clojure programmers congregate continues to be an inspiration and example to me. In particular, many of the
regular denizens of #clojure on Freenode IRC—in addition to becoming good
friends—have guided me toward learning things I never would have otherwise.
To my coauthors, Christophe and Brian: working with you has been a great honor for
me. There is absolutely no way that I would have been able to complete this work
without you.
To my parents, Charley and Darleen: my compulsive curiosity about how things work,
my love of language and rhetoric, and my interest in business—all of these can be traced
back over the years to your consistent influence. Without it, I am certain I would not
have found my unique path, started a software company, or written this book, each
done against all odds.
Preface | xv
www.it-ebooks.info
Finally, to my wife, Krissy: the sacrifices you’ve made to enable me to chase my ambitions are legion. It is likely that I’ll never be able to thank you sufficiently. So, I’ll just
say: I love you.
—Chas Emerick, February 2012
To everyone in the community who helped create Clojure: thank you for your tireless
hard work, for making my professional and personal coding life so much more enjoyable, and for opening my eyes to what’s possible.
To my coauthors, Christophe and Chas: I’ve never worked with a smarter group of
people. It’s been an honor and a privilege.
To my wife Nicole: sorry I kept you awake all night with my typing.
—Brian Carper, February 2012
To Rich Hickey for creating Clojure and fostering such a friendly community.
To this community for having brought me to higher standards.
To my coauthors, Brian and Chas: it has been a great honor to work with you.
A mon professeur Daniel Goffinet, et à ses exercices improbables, qui a radicalement
changé mon approche de la programmation et de l’informatique—sur ces sujets je lui
suis plus redevable qu’à nul autre.
(To Pr. Daniel Goffinet, and his meta mind twisters, who radically altered the way I
think about programming and computing—on those subjects there is no one I’m more
indebted to.)
A mes parents pour votre amour bien sûr mais aussi pour tout le temps à s’inquiéter
que je passais trop de temps sur l’Amstrad.
(To my parents: for your love obviously and for buying me that 8-bit computer you
worried I was spending too much time on.)
A ma compagne Emilie, et mon fils Gaël, merci d’être là et de m’avoir supporté pendant
l’écriture de ce livre.
(To my wife Emilie and to my son Gaël: thank you for being there and having supported
me throughout the writing of this book.)
—Christophe Grand, February 2012
Conventions Used in This Book
The following typographical conventions are used in this book:
Italic
Indicates new terms, URLs, email addresses, filenames, and file extensions.
xvi | Preface
www.it-ebooks.info
Constant width
Used for program listings, as well as within paragraphs to refer to program elements
such as variable or function names, databases, data types, environment variables,
statements, and keywords.
; listing lines prefixed with a semicolon
Used to indicate content printed (i.e., to standard out/err) by code evaluated in the
REPL.
;= listing lines prefixed with a semicolon + equal sign
Used to indicate the result/return value of a REPL evaluation.
Constant width bold
Shows commands or other text that should be typed literally by the user.
Constant width italic
Shows text that should be replaced with user-supplied values or by values determined by context.
This icon signifies a tip, suggestion, or general note.
This icon indicates a warning or caution.
Using Code Examples
This book is here to help you get your job done. In general, you may use the code in
this book in your programs and documentation. You do not need to contact us for
permission unless you’re reproducing a significant portion of the code. For example,
writing a program that uses several chunks of code from this book does not require
permission. Selling or distributing a CD-ROM of examples from O’Reilly books does
require permission. Answering a question by citing this book and quoting example
code does not require permission. Incorporating a significant amount of example code
from this book into your product’s documentation does require permission.
We appreciate, but do not require, attribution. An attribution usually includes the title,
author, publisher, and ISBN. For example: “Clojure Programming by Chas Emerick,
Brian Carper, and Christophe Grand (O’Reilly). Copyright 2012 Chas Emerick, Brian
Carper, and Christophe Grand, 978-1-449-39470-7.”
If you feel your use of code examples falls outside fair use or the permission given above,
feel free to contact us at
[email protected].
Preface | xvii
www.it-ebooks.info
Safari® Books Online
Safari Books Online is an on-demand digital library that lets you easily
search over 7,500 technology and creative reference books and videos to
find the answers you need quickly.
With a subscription, you can read any page and watch any video from our library online.
Read books on your cell phone and mobile devices. Access new titles before they are
available for print, and get exclusive access to manuscripts in development and post
feedback for the authors. Copy and paste code samples, organize your favorites, download chapters, bookmark key sections, create notes, print out pages, and benefit from
tons of other time-saving features.
O’Reilly Media has uploaded this book to the Safari Books Online service. To have full
digital access to this book and others on similar topics from O’Reilly and other publishers, sign up for free at http://my.safaribooksonline.com.
How to Contact Us
Please address comments and questions concerning this book to the publisher:
O’Reilly Media, Inc.
1005 Gravenstein Highway North
Sebastopol, CA 95472
800-998-9938 (in the United States or Canada)
707-829-0515 (international or local)
707-829-0104 (fax)
We have a web page for this book, where we list errata, examples, and any additional
information. You can access this page at:
http://shop.oreilly.com/product/0636920013754.do
To comment or ask technical questions about this book, send email to:
[email protected]
For more information about our books, courses, conferences, and news, see our website
at http://www.oreilly.com.
Find us on Facebook: http://facebook.com/oreilly
Follow us on Twitter: http://twitter.com/oreillymedia
Watch us on YouTube: http://www.youtube.com/oreillymedia
xviii | Preface
www.it-ebooks.info