Contents
foreword
preface
acknowledgments
about this book
Part 1 Foundations
- Chapter 1 Clojure philosophy
- The Clojure way
- Why a(nother) Lisp?
- Functional programming
- Why Clojure isn’t especially object-oriented
- Summary
- Chapter 2 Drinking from the Clojure firehose
- Scalars
- Putting things together: collections
- Making things happen: functions
- Vars
- Locals, loops, and blocks
- Preventing things from happening: quoting
- Leveraging Java via interop
- Exceptional circumstances
- Namespaces
- Summary
- Chapter 3 Dipping our toes in the pool
- Truthiness
- Nil pun with care
- Destructuring
- Using the REPL to experiment
- Summary
Part 2 Data types
- Chapter 4 On scalars
- Understanding precision
- Trying to be rational
- When to use keywords
- Symbolic resolution
- Regular expressions—the second problem
- Summary
- Chapter 5 Composite data types
- Persistence, sequences, and complexity
- Vectors: creating and using them in all their varieties
- Lists: Clojure’s code form data structure
- How to use persistent queues
- Persistent sets
- Thinking in maps
- Putting it all together: finding the position of items in a sequence
- Summary
Part 3 Functional programming
- Chapter 6 Being lazy and set in your ways
- On immutability
- Designing a persistent toy
- Laziness
- Putting it all together: a lazy quicksort
- Summary
- Chapter 7 Functional programming
- Functions in all their forms
- Closures
- Thinking recursively
- Putting it all together: A* pathfinding
- Summary
Part 4 Large-scale design
- Chapter 8 Macros
- Data is code is data
- Defining control structures
- Macros combining forms
- Using macros to change forms
- Using macros to control symbolic resolution time
- Using macros to manage resources
- Putting it all together: macros returning functions
- Summary
- Chapter 9 Combining data and code
- Namespaces
- Exploring Clojure multimethods with the Universal Design Pattern
- Types, protocols, and records
- Putting it all together: a fluent builder for chess moves
- Summary
- Chapter 10 Java.next
- Generating objects on the fly with proxy
- Clojure gen-class and GUI programming
- Clojure’s relationship to Java arrays
- All Clojure functions implement...
- Using Clojure data structures in Java APIs
- definterface
- Be wary of exceptions
- Summary
- Chapter 11 Mutation
- Software transactional memory with multiversion concurrency control and snapshot isolation
- When to use Refs
- When to use Agents
- When to use Atoms
- When to use locks
- When to use futures
- When to use promises
- Parallelism
- Vars and dynamic binding
- Summary
Part 5 Tangential considerations
- Chapter 12 Performance
- Type hints
- Transients
- Chunked sequences
- Memoization
- Understanding coercion
- Summary
- Chapter 13 Clojure changes the way you think
- DSLs
- Testing
- A lack of design patterns
- Error handling and debugging
- Fare thee well
resources
index