Table of Contents

Copyright

Brief Table of Contents

Table of Contents

Foreword

Preface

Acknowledgments

About This Book

1. Foundations

Chapter 1. Clojure philosophy

1.1. The Clojure way

1.1.1. Simplicity

1.1.2. Freedom to focus

1.1.3. Empowerment

1.1.4. Clarity

1.1.5. Consistency

1.2. Why a(nother) Lisp?

1.2.1. Beauty

1.2.2. Extreme flexibility

1.2.3. Code is data

1.3. Functional programming

1.3.1. A workable definition of functional programming

1.3.2. The implications of functional programming

1.4. Why Clojure isn’t especially object-oriented

1.4.1. Defining terms

1.4.2. Imperative “baked in”

1.4.3. Most of what OOP gives you, Clojure provides

1.5. Summary

Chapter 2. Drinking from the Clojure firehose

2.1. Scalars

2.1.1. Numbers

2.1.2. Integers

2.1.3. Floating-point numbers

2.1.4. Rationals

2.1.5. Symbols

2.1.6. Keywords

2.1.7. Strings

2.1.8. Characters

2.2. Putting things together: collections

2.2.1. Lists

2.2.2. Vectors

2.2.3. Maps

2.2.4. Sets

2.3. Making things happen: functions

2.3.1. Calling functions

2.3.2. Defining functions

2.3.3. Simplifying function definitions with def and defn

2.3.4. In-place functions with #()

2.4. Vars

2.4.1. Declaring bindings using def

2.5. Locals, loops, and blocks

2.5.1. Blocks

2.5.2. Locals

2.5.3. Loops

2.6. Preventing things from happening: quoting

2.6.1. Evaluation

2.6.2. Quoting

2.6.3. Unquote

2.6.4. Unquote-splicing

2.6.5. Auto-gensym

2.7. Leveraging Java via interop

2.7.1. Accessing static class members

2.7.2. Creating Java class instances

2.7.3. Accessing Java instance members with the . operator

2.7.4. Setting Java instance properties

2.7.5. The .. macro

2.7.6. The doto macro

2.7.7. Defining classes

2.8. Exceptional circumstances

2.8.1. A little pitch and catch

2.9. Namespaces

2.9.1. Creating namespaces using ns

2.9.2. Loading other namespaces with :require

2.9.3. Loading and creating mappings with :use

2.9.4. Creating mappings with :refer

2.9.5. Loading Java classes with :import

2.10. Summary

Chapter 3. Dipping our toes in the pool

3.1. Truthiness

3.1.1. What’s truth?

3.1.2. Don’t create Boolean objects

3.1.3. nil versus false

3.2. Nil pun with care

3.3. Destructuring

3.3.1. Your assignment, should you choose to accept it

3.3.2. Destructuring with a vector

3.3.3. Destructuring with a map

3.3.4. Destructuring in function parameters

3.3.5. Destructuring versus accessor methods

3.4. Using the REPL to experiment

3.4.1. Experimenting with seqs

3.4.2. Experimenting with graphics

3.4.3. Putting It All Together

3.4.4. When things go wrong

3.4.5. Just for fun

3.5. Summary

2. Data types

Chapter 4. On scalars

4.1. Understanding precision

4.1.1. Truncation

4.1.2. Promotion

4.1.3. Overflow

4.1.4. Underflow

4.1.5. Rounding errors

4.2. Trying to be rational

4.2.1. Why be rational?

4.2.2. How to be rational

4.2.3. Caveats of rationality

4.3. When to use keywords

4.3.1. How are keywords different from symbols?

4.3.2. Qualifying your keywords

4.4. Symbolic resolution

4.4.1. Metadata

4.4.2. Symbols and namespaces

4.4.3. Lisp-1

4.5. Regular expressions—the second problem

4.5.1. Syntax

4.5.2. Functions

4.5.3. Beware of mutable matchers

4.6. Summary

Chapter 5. Composite data types

5.1. Persistence, sequences, and complexity

5.1.1. “You keep using that word. I do not think it means what you think it means.”

5.1.2. Sequence terms and what they mean

5.1.3. Big-O

5.2. Vectors: creating and using them in all their varieties

5.2.1. Building vectors

5.2.2. Large vectors

5.2.3. Vectors as stacks

5.2.4. Using vectors instead of reverse

5.2.5. Subvectors

5.2.6. Vectors as MapEntries

5.2.7. What vectors aren’t

5.3. Lists: Clojure’s code form data structure

5.3.1. Lists like Lisps like

5.3.2. Lists as stacks

5.3.3. What lists aren’t

5.4. How to use persistent queues

5.4.1. A queue about nothing

5.4.2. Putting things on

5.4.3. Getting things

5.4.4. Taking things off

5.5. Persistent sets

5.5.1. Basic properties of Clojure sets

5.5.2. Keeping your sets in order with sorted-set

5.5.3. contains?

5.5.4. clojure.set

5.6. Thinking in maps

5.6.1. Hash maps

5.6.2. Keeping your keys in order with sorted maps

5.6.3. Keeping your insertions in order with array maps

5.7. Putting it all together: finding the position of items in a sequence

5.7.1. Implementation

5.8. Summary

3. Functional programming

Chapter 6. Being lazy and set in your ways

6.1. On immutability

6.1.1. Defining immutability

6.1.2. Being set in your ways—immutability

6.2. Designing a persistent toy

6.3. Laziness

6.3.1. Familiar laziness with logical-and

6.3.2. Understanding the lazy-seq recipe

6.3.3. Losing your head

6.3.4. Employing infinite sequences

6.3.5. The delay and force macros

6.4. Putting it all together: a lazy quicksort

The Implementation

6.5. Summary

Chapter 7. Functional programming

7.1. Functions in all their forms

7.1.1. First-class functions

7.1.2. Higher-order functions

7.1.3. Pure functions

7.1.4. Named arguments

7.1.5. Constraining functions with pre- and postconditions

7.2. Closures

Functions Returning Closures

Closing Over Parameters

Passing Closures as Functions

Sharing Closure Context

7.3. Thinking recursively

7.3.1. Mundane recursion

7.3.2. Tail calls and recur

7.3.3. Don’t forget your trampoline

7.3.4. Continuation-passing style

7.4. Putting it all together: A* pathfinding

The World

Neighbors

7.4.1. The A* implementation

7.4.2. Notes about the A* implementation

7.5. Summary

4. Large-scale design

Chapter 8. Macros

8.1. Data is code is data

8.1.1. Syntax-quote, unquote, and splicing

8.1.2. Macro rules of thumb

8.2. Defining control structures

8.2.1. Defining control structures without syntax-quote

8.2.2. Defining control structures using syntax-quote and unquoting

8.3. Macros combining forms

8.4. Using macros to change forms

8.5. Using macros to control symbolic resolution time

8.5.1. Anaphora

8.5.2. (Arguably) useful selective name capturing

8.6. Using macros to manage resources

8.7. Putting it all together: macros returning functions

8.8. Summary

Chapter 9. Combining data and code

9.1. Namespaces

9.1.1. Creating namespaces

9.1.2. Expose only what’s needed

9.1.3. Declarative inclusions and exclusions

9.2. Exploring Clojure multimethods with the Universal Design Pattern

9.2.1. The parts

9.2.2. Usage

9.2.3. Multimethods to the rescue

9.2.4. Ad hoc hierarchies for inherited behaviors

9.2.5. Resolving conflict in hierarchies

9.2.6. Arbitrary dispatch for true maximum power

9.3. Types, protocols, and records

9.3.1. Records

9.3.2. Protocols

9.3.3. Building from a more primitive base with deftype

9.4. Putting it all together: a fluent builder for chess moves

9.4.1. Java implementation

9.4.2. Clojure implementation

9.5. Summary

Chapter 10. Java.next

10.1. Generating objects on the fly with proxy

10.1.1. A simple dynamic web service

10.2. Clojure gen-class and GUI programming

10.2.1. Namespaces as class specifications

10.2.2. Exploring user interface design and development with Clojure

10.3. Clojure’s relationship to Java arrays

10.3.1. Types of arrays: primitive and reference

10.3.2. Array mutability

10.3.3. That unfortunate naming convention

10.3.4. Multidimensional arrays

10.3.5. Variadic method/constructor calls

10.4. All Clojure functions implement...

10.4.1. java.util.Comparator

10.4.2. java.lang.Runnable

10.4.3. java.util.concurrent.Callable

10.5. Using Clojure data structures in Java APIs

10.5.1. java.util.List

10.5.2. java.lang.Comparable

10.5.3. java.util.RandomAccess

10.5.4. java.util.Collection

10.5.5. java.util.Set

10.6. definterface

10.6.1. Generating interfaces on the fly

10.7. Be wary of exceptions

10.7.1. A bit of background regarding exceptions

10.7.2. Runtime versus compile-time exceptions

10.7.3. Handling exceptions

10.7.4. Custom exceptions

10.8. Summary

Chapter 11. Mutation

11.1. Software transactional memory with multiversion concurrency control and snapshot isolation

11.1.1. Transactions

11.1.2. Embedded transactions

11.1.3. The things that STM makes easy

11.1.4. Potential downsides

11.1.5. The things that make STM unhappy

11.2. When to use Refs

11.2.1. Coordinated, synchronous change using alter

11.2.2. Commutative change with commute

11.2.3. Vulgar change with ref-set

11.2.4. Fixing write-skew with ensure

11.2.5. Refs under stress

11.3. When to use Agents

11.3.1. In-process versus distributed concurrency models

11.3.2. Controlling I/O with an Agent

11.3.3. The difference between send and send-off

11.3.4. Error handling

11.3.5. When not to use Agents

11.4. When to use Atoms

11.4.1. Sharing across threads

11.4.2. Using Atoms in transactions

11.5. When to use locks

11.5.1. Safe mutation through locking

11.5.2. Using Java’s explicit locks

11.6. When to use futures

11.6.1. Futures as callbacks

11.7. When to use promises

11.7.1. Parallel tasks with promises

11.7.2. Callback API to blocking API

11.7.3. Deterministic deadlocks

11.8. Parallelism

11.8.1. pvalues

11.8.2. pmap

11.8.3. pcalls

11.9. Vars and dynamic binding

11.9.1. The binding macro

11.9.2. Creating a named Var

11.9.3. Creating anonymous Vars

11.9.4. Dynamic scope

11.10. Summary

5. Tangential considerations

Chapter 12. Performance

12.1. Type hints

12.1.1. Advantages of type adornment

12.1.2. Type-hinting arguments and returns

12.1.3. Type-hinting objects

12.2. Transients

12.2.1. Ephemeral garbage

12.2.2. Transients compare in efficiency to mutable collections

12.3. Chunked sequences

12.3.1. Regaining one-at-a-time laziness

12.4. Memoization

12.4.1. Re-examining memoization

12.4.2. A memoization protocol

12.5. Understanding coercion

12.5.1. First rule of coercion: don’t

12.5.2. Corollary: you’re probably not doing it right

12.5.3. Second rule of coercion: don’t

12.5.4. Third rule of coercion: coerce a stable local

12.5.5. Fourth rule of coercion: watch your sizes

12.5.6. Fifth rule of coercion: truncate only as a goal

12.6. Summary

Chapter 13. Clojure changes the way you think

13.1. DSLs

13.1.1. A ubiquitous DSL

13.1.2. Putting parentheses around the specification

13.1.3. A note about Clojure’s approach to DSLs

13.2. Testing

13.2.1. Some useful techniques

13.2.2. Contracts programming

13.3. A lack of design patterns

13.3.1. Clojure’s first-class design patterns

13.4. Error handling and debugging

13.4.1. Error handling

13.4.2. Debugging

13.5. Fare thee well

 Resources

Miscellaneous resources

Online resources

Index

List of Figures

List of Tables

List of Listings

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.143.5.217