Cover image for Clojure Programming

Book description

The Clojure language is a practical alternative for everyday programming that offers expressivity rivaling other dynamic languages like Ruby and Python, but allows one to seamlessly take advantage of Java libraries, services, and all of the resources of the JVM ecosystem. This book helps you learn the fundamentals of Clojure with examples relating it to the languages you know already—whether you're focused on data modeling, concurrency and parallelism, web programming, statistics and data analysis, and more.

Table of Contents

  1. Clojure Programming
  2. SPECIAL OFFER: Upgrade this ebook with O’Reilly
  3. Preface
    1. Who Is This Book For?
      1. Engaged Java Developers
      2. Ruby, Python, and Other Developers
    2. How to Read This Book
      1. Start with Practical Applications of Clojure
      2. Start from the Ground Up with Clojure’s Foundational Concepts
    3. Who’s “We”?
      1. Chas Emerick
      2. Brian Carper
      3. Christophe Grand
    4. Acknowledgments
      1. And Last, but Certainly Far from Least
    5. Conventions Used in This Book
    6. Using Code Examples
    7. Safari® Books Online
    8. How to Contact Us
  4. 1. Down the Rabbit Hole
    1. Why Clojure?
    2. Obtaining Clojure
    3. The Clojure REPL
    4. No, Parentheses Actually Won’t Make You Go Blind
    5. Expressions, Operators, Syntax, and Precedence
    6. Homoiconicity
    7. The Reader
      1. Scalar Literals
        1. Strings
        2. Booleans
        3. nil
        4. Characters
        5. Keywords
        6. Symbols
        7. Numbers
        8. Regular expressions
      2. Comments
      3. Whitespace and Commas
      4. Collection Literals
      5. Miscellaneous Reader Sugar
    8. Namespaces
    9. Symbol Evaluation
    10. Special Forms
      1. Suppressing Evaluation: quote
      2. Code Blocks: do
      3. Defining Vars: def
      4. Local Bindings: let
      5. Destructuring (let, Part 2)
        1. Sequential destructuring
        2. Map destructuring
      6. Creating Functions: fn
        1. Destructuring function arguments
        2. Function literals
      7. Conditionals: if
      8. Looping: loop and recur
      9. Referring to Vars: var
      10. Java Interop: . and new
      11. Exception Handling: try and throw
      12. Specialized Mutation: set!
      13. Primitive Locking: monitor-enter and monitor-exit
    11. Putting It All Together
      1. eval
    12. This Is Just the Beginning
  5. I. Functional Programming and Concurrency
    1. 2. Functional Programming
      1. What Does Functional Programming Mean?
      2. On the Importance of Values
        1. About Values
        2. Comparing Values to Mutable Objects
        3. A Critical Choice
      3. First-Class and Higher-Order Functions
        1. Applying Ourselves Partially
      4. Composition of Function(ality)
        1. Writing Higher-Order Functions
        2. Building a Primitive Logging System with Composable Higher-Order Functions
      5. Pure Functions
        1. Why Are Pure Functions Interesting?
      6. Functional Programming in the Real World
    2. 3. Collections and Data Structures
      1. Abstractions over Implementations
        1. Collection
        2. Sequences
          1. Sequences are not iterators
          2. Sequences are not lists
          3. Creating seqs
          4. Lazy seqs
          5. Head retention
        3. Associative
          1. Beware of nil values
        4. Indexed
        5. Stack
        6. Set
        7. Sorted
          1. Comparators and predicates to define ordering
      2. Concise Collection Access
        1. Idiomatic Usage
        2. Collections and Keys and Higher-Order Functions
      3. Data Structure Types
        1. Lists
        2. Vectors
          1. Vectors as tuples
        3. Sets
        4. Maps
          1. Maps as ad-hoc structs
          2. Other usages of maps
      4. Immutability and Persistence
        1. Persistence and Structural Sharing
          1. Visualizing persistence: lists
          2. Visualizing persistence: maps (and vectors and sets)
          3. Tangible benefits
        2. Transients
      5. Metadata
      6. Putting Clojure’s Collections to Work
        1. Identifiers and Cycles
        2. Thinking Different: From Imperative to Functional
          1. Revisiting a classic: Conway’s Game of Life
          2. Maze generation
        3. Navigation, Update, and Zippers
          1. Manipulating zippers
          2. Custom zippers
          3. Ariadne’s zipper
      7. In Summary
    3. 4. Concurrency and Parallelism
      1. Shifting Computation Through Time and Space
        1. Delays
        2. Futures
        3. Promises
      2. Parallelism on the Cheap
      3. State and Identity
      4. Clojure Reference Types
      5. Classifying Concurrent Operations
      6. Atoms
      7. Notifications and Constraints
        1. Watches
        2. Validators
      8. Refs
        1. Software Transactional Memory
        2. The Mechanics of Ref Change
          1. Understanding alter
          2. Minimizing transaction conflict with commute
          3. Clobbering ref state with ref-set
          4. Enforcing local consistency by using validators
        3. The Sharp Corners of Software Transactional Memory
          1. Side-effecting functions strictly verboten
          2. Minimize the scope of each transaction
          3. Readers may retry
          4. Write skew
      9. Vars
        1. Defining Vars
          1. Private vars
          2. Docstrings
          3. Constants
        2. Dynamic Scope
        3. Vars Are Not Variables
        4. Forward Declarations
      10. Agents
        1. Dealing with Errors in Agent Actions
          1. Agent error handlers and modes
        2. I/O, Transactions, and Nested Sends
          1. Persisting reference states with an agent-based write-behind log
          2. Using agents to parallelize workloads
      11. Using Java’s Concurrency Primitives
        1. Locking
      12. Final Thoughts
  6. II. Building Abstractions
    1. 5. Macros
      1. What Is a Macro?
        1. What Macros Are Not
        2. What Can Macros Do that Functions Cannot?
        3. Macros Versus Ruby eval
      2. Writing Your First Macro
      3. Debugging Macros
        1. Macroexpansion
      4. Syntax
        1. quote Versus syntax-quote
        2. unquote and unquote-splicing
      5. When to Use Macros
      6. Hygiene
        1. Gensyms to the Rescue
        2. Letting the User Pick Names
        3. Double Evaluation
      7. Common Macro Idioms and Patterns
      8. The Implicit Arguments: &env and &form
        1. &env
        2. &form
          1. Producing useful macro error messages
          2. Preserving user-provided type hints
        3. Testing Contextual Macros
      9. In Detail: -> and ->>
      10. Final Thoughts
    2. 6. Datatypes and Protocols
      1. Protocols
      2. Extending to Existing Types
      3. Defining Your Own Types
        1. Records
          1. Constructors and factory functions
          2. When to use maps or records
        2. Types
      4. Implementing Protocols
        1. Inline Implementation
          1. Inline implementations of Java interfaces
          2. Defining anonymous types with reify
        2. Reusing Implementations
      5. Protocol Introspection
      6. Protocol Dispatch Edge Cases
      7. Participating in Clojure’s Collection Abstractions
      8. Final Thoughts
    3. 7. Multimethods
      1. Multimethods Basics
      2. Toward Hierarchies
      3. Hierarchies
        1. Independent Hierarchies
      4. Making It Really Multiple!
      5. A Few More Things
        1. Multiple Inheritance
        2. Introspecting Multimethods
        3. type Versus class; or, the Revenge of the Map
        4. The Range of Dispatch Functions Is Unlimited
      6. Final Thoughts
  7. III. Tools, Platform, and Projects
    1. 8. Organizing and Building Clojure Projects
      1. Project Geography
        1. Defining and Using Namespaces
          1. Namespaces and files
          2. A classpath primer
        2. Location, Location, Location
        3. The Functional Organization of Clojure Codebases
          1. Basic project organization principles
      2. Build
        1. Ahead-of-Time Compilation
        2. Dependency Management
        3. The Maven Dependency Management Model
          1. Artifacts and coordinates
          2. Repositories
          3. Dependencies
        4. Build Tools and Configuration Patterns
          1. Maven
          2. Leiningen
          3. AOT compilation configuration
          4. Building mixed-source projects
      3. Final Thoughts
    2. 9. Java and JVM Interoperability
      1. The JVM Is Clojure’s Foundation
      2. Using Java Classes, Methods, and Fields
      3. Handy Interop Utilities
      4. Exceptions and Error Handling
        1. Escaping Checked Exceptions
        2. with-open, finally’s Lament
      5. Type Hinting for Performance
      6. Arrays
      7. Defining Classes and Implementing Interfaces
        1. Instances of Anonymous Classes: proxy
        2. Defining Named Classes
          1. gen-class
        3. Annotations
          1. Producing annotated JUnit tests
          2. Implementing JAX-RS web service endpoints
      8. Using Clojure from Java
        1. Using deftype and defrecord Classes
        2. Implementing Protocol Interfaces
      9. Collaborating Partners
    3. 10. REPL-Oriented Programming
      1. Interactive Development
        1. The Persistent, Evolving Environment
      2. Tooling
        1. The Bare REPL
          1. Introspecting namespaces
        2. Eclipse
        3. Emacs
          1. clojure-mode and paredit
          2. inferior-lisp
          3. SLIME
      3. Debugging, Monitoring, and Patching Production in the REPL
        1. Special Considerations for “Deployed” REPLs
      4. Limitations to Redefining Constructs
      5. In Summary
  8. IV. Practicums
    1. 11. Numerics and Mathematics
      1. Clojure Numerics
        1. Clojure Prefers 64-bit (or Larger) Representations
        2. Clojure Has a Mixed Numerics Model
        3. Rationals
        4. The Rules of Numeric Contagion
      2. Clojure Mathematics
        1. Bounded Versus Arbitrary Precision
        2. Unchecked Ops
        3. Scale and Rounding Modes for Arbitrary-Precision Decimals Ops
      3. Equality and Equivalence
        1. Object Identity (identical?)
        2. Reference Equality (=)
        3. Numeric Equivalence (==)
          1. Equivalence can preserve your sanity
      4. Optimizing Numeric Performance
        1. Declare Functions to Take and Return Primitives
          1. Type errors and warnings
        2. Use Primitive Arrays Judiciously
          1. The mechanics of primitive arrays
          2. Automating type hinting of multidimensional array operations
      5. Visualizing the Mandelbrot Set in Clojure
    2. 12. Design Patterns
      1. Dependency Injection
      2. Strategy Pattern
      3. Chain of Responsibility
      4. Aspect-Oriented Programming
      5. Final Thoughts
    3. 13. Testing
      1. Immutable Values and Pure Functions
        1. Mocking
      2. clojure.test
        1. Defining Tests
        2. Test “Suites”
        3. Fixtures
      3. Growing an HTML DSL
      4. Relying upon Assertions
        1. Preconditions and Postconditions
    4. 14. Using Relational Databases
      1. clojure.java.jdbc
        1. with-query-results Explained
        2. Transactions
        3. Connection Pooling
      2. Korma
        1. Prelude
        2. Queries
        3. Why Bother with a DSL?
      3. Hibernate
        1. Setup
        2. Persisting Data
        3. Running Queries
        4. Removing Boilerplate
      4. Final Thoughts
    5. 15. Using Nonrelational Databases
      1. Getting Set Up with CouchDB and Clutch
      2. Basic CRUD Operations
      3. Views
        1. A Simple (JavaScript) View
        2. Views in Clojure
      4. _changes: Abusing CouchDB as a Message Queue
      5. À la Carte Message Queues
      6. Final Thoughts
    6. 16. Clojure and the Web
      1. The “Clojure Stack”
      2. The Foundation: Ring
        1. Requests and Responses
        2. Adapters
        3. Handlers
        4. Middleware
      3. Routing Requests with Compojure
      4. Templating
        1. Enlive: Selector-Based HTML Transformation
          1. Testing the waters
          2. Selectors
          3. Iterating and branching
          4. Putting everything together
      5. Final Thoughts
    7. 17. Deploying Clojure Web Applications
      1. Java and Clojure Web Architecture
        1. Web Application Packaging
          1. Building .war files with Maven
          2. Building .war files with Leiningen
      2. Running Web Apps Locally
      3. Web Application Deployment
        1. Deploying Clojure Apps to Amazon’s Elastic Beanstalk
      4. Going Beyond Simple Web Application Deployment
  9. V. Miscellanea
    1. 18. Choosing Clojure Type Definition Forms Wisely
    2. 19. Introducing Clojure into Your Workplace
      1. Just the Facts…
      2. Emphasize Productivity
      3. Emphasize Community
      4. Be Prudent
    3. 20. What’s Next?
      1. (dissoc Clojure 'JVM)
        1. ClojureCLR
        2. ClojureScript
      2. 4Clojure
      3. Overtone
      4. core.logic
      5. Pallet
      6. Avout
      7. Clojure on Heroku
  10. Index
  11. About the Authors
  12. Colophon
  13. SPECIAL OFFER: Upgrade this ebook with O’Reilly