Elegant applications on the JVM IN ACTION Amit Rathore M A N N I N G Clojure in Action Clojure in Action AMIT RATHORE MANNING SHELTER ISLAND To my parents, my son, and my wonderful wife For online information and ordering of this and other Manning books, please visit www.manning.com. The publisher offers discounts on this book when ordered in quantity. For more information, please contact Special Sales Department Manning Publications Co. 20 Baldwin Road PO Box 261 Shelter Island, NY 11964 Email: [email protected] ©2012 by Manning Publications Co. All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by means electronic, mechanical, photocopying, or otherwise, without prior written permission of the publisher. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in the book, and Manning Publications was aware of a trademark claim, the designations have been printed in initial caps or all caps. Recognizing the importance of preserving what has been written, it is Manning’s policy to have the books we publish printed on acid-free paper, and we exert our best efforts to that end. Recognizing also our responsibility to conserve the resources of our planet, Manning books are printed on paper that is at least 15 percent recycled and processed without the use of elemental chlorine. Manning Publications Co. Development editor: Susan Harkins 20 Baldwin Road Copyeditors: Linda Recktenwald PO Box 261 Typesetter: Dennis Dalinnik Shelter Island, NY 11964 Cover designer: Marija Tudor ISBN: 9781935182597 Printed in the United States of America 1 2 3 4 5 6 7 8 9 10 – MAL – 17 16 15 14 13 12 11 brief contents PART 1 GETTING STARTED........................................................1 1 ■ Introduction to Clojure 3 2 ■ A whirlwind tour 30 3 ■ Building blocks of Clojure 60 4 ■ Polymorphism with multimethods 90 5 ■ Clojure and Java interop 106 6 ■ State and the concurrent world 122 7 ■ Evolving Clojure through macros 148 PART 2 GETTING REAL..........................................................167 8 ■ Test-driven development and more 169 9 ■ Data storage with Clojure 189 10 ■ Clojure and the web 221 11 ■ Scaling through messaging 240 12 ■ Data processing with Clojure 273 13 ■ More on functional programming 307 14 ■ Protocols, records, and types 339 15 ■ More macros and DSLs 367 v contents preface xiii acknowledgments xvi about this book xviii PART 1 GETTING STARTED.............................................1 1 Introduction to Clojure 3 1.1 What is Clojure? 4 Clojure—the reincarnation of Lisp 4 ■ How we got here 5 How this book teaches Clojure 5 1.2 Understanding Clojure syntax 6 XML and parentheses 7 ■ Lists, vectors, and hashes 9 1.3 The sources of Clojure’s power 10 Clojure and Lisp 10 ■ Clojure and functional programming 11 Clojure and the JVM 11 ■ Clojure as a Lisp 11 More advantages of Clojure 18 ■ Clojure as a functional language 18 ■ Clojure as a JVM-based language 23 1.4 Clojure—beyond object orientation 26 1.5 Summary 28 vii viii CONTENTS 2 A whirlwind tour 30 2.1 Getting started 30 Installing Clojure 31 ■ The Clojure REPL 31 Hello, world 32 ■ doc and find-doc 33 ■ A few more points on Clojure syntax 34 2.2 Program structure 36 Functions 36 ■ The let form 37 ■ Side effects with do 39 try/catch/finally and throw 40 ■ Reader macros 41 2.3 Program flow 42 Conditionals 43 ■ Functional iteration 45 The threading macros 50 2.4 Clojure data structures 52 nil, truth, and falsehood 52 ■ Chars, strings, and numbers 52 Keywords and symbols 53 ■ Sequences 53 2.5 Summary 58 3 Building blocks of Clojure 60 3.1 Functions 61 Defining functions 61 ■ Calling functions 67 Higher-order functions 67 ■ Anonymous functions 70 Keywords and symbols 71 3.2 Scope 73 Vars and binding 74 ■ The let form revisited 78 Lexical closures 79 3.3 Namespaces 80 ns 80 ■ Working with namespaces 83 3.4 Destructuring 83 Vector bindings 84 ■ Map bindings 86 3.5 Metadata 88 3.6 Summary 89 4 Polymorphism with multimethods 90 4.1 Polymorphism 91 Subtype polymorphism 91 ■ Duck typing 92 4.2 Method dispatch 92 Single and double dispatch 93 ■ The visitor pattern (and simulating double dispatch) 95 ■ Multiple dispatch 96 CONTENTS ix 4.3 Multimethods 97 Without multimethods 97 ■ Using multimethods 97 Multiple dispatch 99 ■ Ad hoc hierarchies 100 Redis-clojure 103 4.4 Summary 104 5 Clojure and Java interop 106 5.1 Calling Java from Clojure 107 Importing Java classes into Clojure 107 ■ Creating instances and accessing methods and fields 108 ■ memfn 112 bean 113 ■ Arrays 113 ■ Implementing interfaces and extending classes 114 5.2 Compiling Clojure code to Java byte code 115 Example–a tale of two calculators 115 ■ Creating Java classes and interfaces using gen-class and gen-interface 117 5.3 Calling Clojure from Java 120 5.4 Summary 121 6 State and the concurrent world 122 6.1 The problem with state 123 Common problems with shared state 123 The traditional solution 124 6.2 Identities and values 125 Immutable values 126 ■ Objects and time 127 Immutability and concurrency 128 6.3 The Clojure way 129 Requirements for immutability 130 ■ Managed references 131 6.4 Refs 131 Mutating refs 132 ■ Software transactional memory 134 6.5 Agents 136 Mutating agents 136 ■ Working with agents 137 Side effects in STM transactions 139 6.6 Atoms 140 Mutating atoms 141 6.7 Vars 142 6.8 State and its unified access model 143 6.9 Watching for mutation 144