Clojure is a relatively new version of Lisp that runs on the Java Virtual Machine. It's a functional language, which means that it's ideal for the growing need for concurrent programming and for specialized tasks like creating domain specific languages.
Clojure in Action, Second Edition is a fully-revised edition that covers the new features available in Clojure 1.5. This easy-to-follow tutorial provides a rapid introduction to the Clojure language and starts by showing how to use Clojure as a general purpose language. It looks at Clojure's efficient concurrency model, which is based on the familiar database concept of Software Transactional Memory (STM) and helps readers find a new level of productivity through Clojure DSLs that run on the JVM. Using this book, readers will discover countless tips, tricks, and techniques for writing smaller, faster, and safer code.
Purchase of the print book comes with an offer of a free PDF, ePub, and Kindle eBook from Manning. Also available is all code from the book.
Author(s): Amit Rathore
Edition: 2
Publisher: Manning Publications
Year: 2015
Language: English
Commentary: True PDF
Pages: 450
Front cover
Title Page
Copyright
contents
preface to the second edition
preface to the first edition
acknowledgments
about this book
How to use this book
Roadmap
Code conventions and downloads
Author Online
About the cover illustration
1 Introducing Clojure
1.1 Clojure: What and why?
1.1.1 Clojure: A modern Lisp
1.1.2 Clojure: Pragmatic functional programming
1.1.3 Clojure on the JVM
1.2 Language basics
1.2.1 Lisp syntax
1.2.2 Parentheses
1.3 Host interoperation: A JVM crash course
1.3.1 Java types, classes, and objects
1.3.2 The dot and new operators
1.3.3 Threads and concurrency
1.4 Summary
2 Clojure elements: Data structures and functions
2.1 Coding at the REPL
2.1.1 Clojure REPL
2.1.2 “Hello, world!”
2.1.3 Looking up documentation using doc, find-doc, and apropos
2.1.4 A few more points on Clojure syntax
2.2 Clojure data structures
2.2.1 nil, truth, and falsehood
2.2.2 Characters and strings
2.2.3 Clojure numbers
2.2.4 Symbols and keywords
2.2.5 Lists
2.2.6 Vectors
2.2.7 Maps
2.2.8 Sequences
2.3 Program structure
2.3.1 Functions
2.3.2 The let form
2.3.3 Side effects with do
2.3.4 Reader macros
2.4 Program flow
2.4.1 Conditionals
2.4.2 Logical functions
2.4.3 Functional iteration
2.4.4 Threading macros
2.5 Summary
3 Building blocks of Clojure
3.1 Metadata
3.1.1 Java type hints
3.1.2 Java primitive and array types
3.2 Java exceptions: try and throw
3.3 Functions
3.3.1 Defining functions
3.3.2 Calling functions
3.3.3 Higher-order functions
3.3.4 Writing higher-order functions
3.3.5 Anonymous functions
3.3.6 Keywords and symbols
3.4 Scope
3.4.1 Vars and binding
3.4.2 The let form revisited
3.4.3 Lexical closures
3.5 Namespaces
3.5.1 ns macro
3.5.2 Working with namespaces
3.6 Destructuring
3.6.1 Vector bindings
3.6.2 Map bindings
3.7 Reader literals
3.8 Summary
4 Multimethod polymorphism
4.1 Polymorphism and its types
4.1.1 Parametric polymorphism
4.1.2 Ad hoc polymorphism
4.1.3 Subtype polymorphism
4.2 Polymorphism using multimethods
4.2.1 Life without multimethods
4.2.2 Ad hoc polymorphism using multimethods
4.2.3 Multiple dispatch
4.2.4 Subtype polymorphism using multimethods
4.3 Summary
5 Exploring Clojure and Java interop
5.1 Calling Java from Clojure
5.1.1 Importing Java classes into Clojure
5.1.2 Creating instances
5.1.3 Accessing methods and fields
5.1.4 Macros and the dot special form
5.1.5 Helpful Clojure macros for working with Java
5.1.6 Implementing interfaces and extending classes
5.2 Compiling Clojure code to Java bytecode
5.2.1 Example: A tale of two calculators
5.2.2 Creating Java classes and interfaces using gen-class and gen-interface
5.3 Calling Clojure from Java
5.4 Summary
6 State and the concurrent world
6.1 The problem with state
6.1.1 Common problems with shared state
6.1.2 Traditional solution
6.2 Separating identities and values
6.2.1 Immutable values
6.2.2 Objects and time
6.2.3 Immutability and concurrency
6.3 Clojure’s way
6.3.1 Immutability and performance
6.3.2 Managed references
6.4 Refs
6.4.1 Creating refs
6.4.2 Mutating refs
6.4.3 Software transactional memory
6.5 Agents
6.5.1 Creating agents
6.5.2 Mutating agents
6.5.3 Working with agents
6.5.4 Side effects in STM transactions
6.6 Atoms
6.6.1 Creating atoms
6.6.2 Mutating atoms
6.7 Vars
6.7.1 Creating vars and root bindings
6.7.2 Var bindings
6.8 State and its unified access model
6.8.1 Creating
6.8.2 Reading
6.8.3 Mutation
6.8.4 Transactions
6.8.5 Watching for mutation
6.9 Deciding which reference type to use
6.10 Futures and promises
6.10.1 Futures
6.10.2 Promises
6.11 Summary
7 Evolving Clojure through macros
7.1 Macro basics
7.1.1 Textual substitution
7.1.2 The unless example
7.1.3 Macro templates
7.1.4 Recap: Why macros?
7.2 Macros from within Clojure
7.2.1 comment
7.2.2 declare
7.2.3 defonce
7.2.4 and
7.2.5 time
7.3 Writing your own macros
7.3.1 infix
7.3.2 randomly
7.3.3 defwebmethod
7.3.4 defnn
7.3.5 assert-true
7.4 Summary
8 More on functional programming
8.1 Using higher-order functions
8.1.1 Collecting results of functions
8.1.2 Reducing lists of things
8.1.3 Filtering lists of things
8.2 Partial application
8.2.1 Adapting functions
8.2.2 Defining functions
8.3 Closures
8.3.1 Free variables and closures
8.3.2 Delayed computation and closures
8.3.3 Closures and objects
8.3.4 An object system for Clojure
8.4 Summary
9 Protocols, records, and types
9.1 The expression problem
9.1.1 Setting up the example scenario
9.1.2 A closer look at the expression problem and some potential solutions
9.1.3 Clojure’s multimethods solution
9.2 Examining the operations side of the expression problem
9.2.1 def-modus-operandi
9.2.2 detail-modus-operandi
9.2.3 Tracking your modus operandi
9.2.4 Error handling and trouble spots in this solution
9.3 Examining the data types side of the expression problem with protocols
9.3.1 defprotocol and extend-protocol
9.3.2 Defining data types with deftype, defrecord, and reify
9.4 Summary
10 Test-driven development and more
10.1 Getting started with TDD: Manipulating dates in strings
10.1.1 First assertion
10.1.2 month-from and year-from
10.1.3 as-string
10.1.4 Incrementing and decrementing
10.1.5 Refactor mercilessly
10.2 Improving tests through mocking and stubbing
10.2.1 Example: Expense finders
10.2.2 Stubbing
10.2.3 Mocking
10.2.4 Mocks versus stubs
10.2.5 Managing stubbing and mocking state
10.3 Organizing tests
10.3.1 The testing macro
10.3.2 The are macro
10.4 Summary
11 More macros and DSLs
11.1 A quick review of macros
11.2 Anaphoric macros
11.2.1 The anaphoric if
11.2.2 The thread-it macro
11.3 Shifting computation to compile time
11.3.1 Example: Rotation ciphers without macros
11.3.2 Making the compiler work harder
11.4 Macro-generating macros
11.4.1 Example template
11.4.2 Implementing make-synonym
11.4.3 Why macro-generating macros
11.5 Domain-specific languages
11.5.1 DSL-driven design
11.5.2 User classification
11.6 Summary
Conclusion
Appendix—Installing Clojure
A.1 Try Clojure
A.2 Clojure.jar
A.3 Leiningen
A.3.1 lein tasks
A.3.2 lein repl
A.3.3 Adding dependencies to a Leiningen project
index
Symbols
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Back cover