Programming in Scala Second Edition Martin Odersky, Lex Spoon, Bill Venners artima ARTIMA PRESS WALNUT CREEK, CALIFORNIA
Contents Contents List of Figures List of Tables List of Listings Foreword Foreword to the First Edition Acknowledgments Introduction xüi xxiv xxvi xxviii xxxvii xxxix xli xlv 1 A Scalable Language 3 1.1 A language that grows on you 4 1.2 What makes Scala scalable? 9 1.3 Why Scala? 12 1.4 Scala's roots 19 1.5 Conclusion 21 2 First Steps in Scala 23 Step 1. Learn to use the Scala interpreter 23 Step 2. Define some variables... 25 Step 3. Define some functions 27 Step 4. Write some Scala scripts 29 Step 5. Loop with while; decide with if 30 xm
Contents Step 6. Iterate with foreach and for 32 Conclusion 35 3 Next Steps in Scala 37 Step 7. Parameterize arrays with types 37 Step 8. Use lists 41 Step 9. Use tuples 46 Step 10. Use sets and maps 47 Step 11. Learn to recognize the functional style 52 Step 12. Read lines from a file 55 Conclusion 58 4 Classes and Objects 59 4.1 Classes, fields, and methods 59 4.2 Semicolon inference. 64 4.3 Singleton objects 65 4.4 A Scala application... Y.. 68 4.5 The Application trait 71 4.6 Conclusion 72 5 Basic Types and Operations 73 5.1 Some basic types. 73 5.2 Literals 74 5.3 Operators are methods 81 5.4 Arithmetic operations 84 5.5 Relational and logical operations.. s-. 85 5.6 Bitwise operations 87 5.7 Object equality..... 88 5.8 Operator precedence and associativity.... 90 5.9 Rich wrappers 93 5.10 Conclusion 93 6 Functional Objects ^ 95 6.1 A specification for class Rational 95 6.2 Constructing a Rational 96 6.3 Reimplementing the tostring method 98 6.4 Checking preconditions 99 6.5 Adding fields 99 xiv
6.6 Self references. 101 6.7 Auxiliary constructors 102 6.8 Private fields and methods 104 6.9 Defining operators. 105 6.10 Identifiers in Scala 107 6.11 Method overloading 110 6.12 Implicit conversions 112 6.13 A word of caution 113 6.14 Conclusion 113 7 Built-in Control Structures 115 7.1 If expressions 116 7.2 While loops 117 7.3 For expressions 120 7.4 Exception handling with try expressions 125 7.5 Match expressions 129 7.6 Living without break and continue... 131 7.7 Variable scope 133 7.8 Refactoring imperative-style code.. 137 7.9 Conclusion 139 8 Functions and Closures 141 8.1 Methods 141 8.2 Local functions 143 8.3 First-class functions 145 8.4 Short forms of function literals 147 8.5 Placeholder syntax 148 8.6 Partially applied functions 149 8.7 Closures 152 8.8 Special function call forms 156 8.9 Tail recursion 159 8.10 Conclusion 163 9 Control Abstraction 165 9.1 Reducing code duplication 165 9.2 Simplifying client code 169 9.3 Currying 171 9.4 Writing new control structures 173 xv
Contents 9.5 By-name parameters 176 9.6 Conclusion 179 10 Composition and Inheritance 181 10.1 A two-dimensional layout library 181 10.2 Abstract classes 182 10.3 Defining parameterless methods 183 10.4 Extending classes 186 10.5 Overriding methods and fields 188 10.6 Defining parametric fields 189 10.7 Invoking superclass constructors. 191 10.8 Using override modifiers 192 10.9 Polymorphism and dynamic binding 194 10.10 Declaring final members 196 10.11 Using composition and inheritance 198 10.12 Implementing above, beside, and tostring 199 10.13 Defining a factory object 201 10.14 Heighten and widen 203 10.15 Putting it all together 207 10.16 Conclusion 208 11 Scala's Hierarchy 209 11.1 Scala's class hierarchy 209 11.2 How primitives are implemented 213 11.3 Bottom types 215 11.4 Conclusion 216 12 Traits 217 12.1 How traits work 217 12.2 Thin versus rich interfaces 220 12.3 Example: Rectangular objects 221 12.4 The Ordered trait 224 12.5 Traits as stackable modifications 226 12.6 Why not multiple inheritance? 230 12.7 To trait, or not to trait? 234 12.8 Conclusion 235 13 Packages and Imports 237 xvi
13.1 Putting code in packages 237 13.2 Concise access to related code 238 13.3 Imports 242 13.4 Implicit imports 246 13.5 Access modifiers 247 13.6 Package objects 252 13.7 Conclusion 254 14 Assertions and Unit Testing 255 14.1 Assertions 255 14.2 Unit testing in Scala 257 14.3 Informative failure reports 258 14.4 Using JUnit and TestNG 260 14.5 Tests as specifications 262 14.6 Property-based testing 265 14.7 Organizing and running tests. 266 14.8 Conclusion 268 15 Case Classes and Pattern Matching 269 15.1 A simple example 269 15.2 Kinds of patterns 274 15.3 Pattern guards 284 15.4 Pattern overlaps. 285 15.5 Sealed classes 286 15.6 The Option type 288 15.7 Patterns everywhere 290 15.8 A larger example 295 15.9 Conclusion 303 16 Working with Lists 305 16.1 List literals 305 16.2 The List type 306 16.3 Constructing lists 306 16.4 Basic operations on lists 307 16.5 List patterns 308 16.6 First-order methods on class List 310 16.7 Higher-order methods on class List 322 16.8 Methods of the List object 330 xvu
Contents 16.9 Processing multiple lists together 332 16.10 Understanding Scala's type inference algorithm 333 16.11 Conclusion 337 17 Collections 339 17.1 Sequences 339 17.2 Sets and maps 343 17.3 Selecting mutable versus immutable collections... 352 17.4 Initializing collections 354 17.5 Tuples 358 17.6 Conclusion 360 18 Stateful Objects 361 18.1 What makes an object stateful? 361 18.2 Reassignable variables and properties 364 18.3 Case study: Discrete event simulation 367 18.4 A language for digital circuits 368 18.5 The Simulation API 371 18.6 Circuit Simulation. 375 18.7 Conclusion 383 19 Type Parameterization 385 19.1 Functional queues 385 19.2 Information hiding 389 19.3 Variance annotations 392 19.4 Checking variance annotations 396 19.5 Lower bounds 399 19.6 Contravariance 401 19.7 Object private data 404 19.8 Upper bounds 406 19.9 Conclusion 409 20 Abstract Members 411 20.1 A quick tour of abstract members 411 20.2 Type members 412 20.3 Abstract vals 413 20.4 Abstract vars 414 20.5 Initializing abstract vals 415 xvin
20.6 Abstract types 423 20.7 Path-dependent types 425 20.8 Structural subtyping 428 20.9 Enumerations 430 20.10 Case study: Currencies 432 20.11 Conclusion 442 21 Implicit Conversions and Parameters 443 21.1 Implicit conversions 443 21.2 Rules for implicits 446 21.3 Implicit conversion to an expected type 449 21.4 Converting the receiver 450 21.5 Implicit parameters 453 21.6 View bounds 459 21.7 When multiple conversions apply 462 21.8 Debugging implicits 465 21.9 Conclusion 466 22 Implementing Lists 467 22.1 The List class in principle 467 22.2 The ListBuff er class 473 22.3 The List class in practice 475 22.4 Functional on the outside 477 22.5 Conclusion 478 23 For Expressions Revisited 481 23.1 For expressions 482 23.2 The n-queens problem 484 23.3 Querying with for expressions 487 23.4 Translation of for expressions 489 23.5 Going the other way 493 23.6 Generalizing for 494 23.7 Conclusion 496 24 The Scala Collections API 497 24.1 Mutable and immutable collections 498 24.2 Collections consistency 500 24.3 Trait Traversable 502 xix
Contents 24.4 Trait It er able 507 24.5 The sequence traits Seq, IndexedSeq, and LinearSeq. 511 24.6 Sets 516 24.7 Maps. (. 522 24.8 Synchronized sets and maps...... 527 24.9 Concrete immutable collection classes 529 24.10 Concrete mutable collection classes 536 24.11 Arrays 543 24.12 Strings 548 24.13 Performance characteristics 549 24.14 Equality.... 550 24.15 Views 552 24.16 Iterators 558 24.17 Creating collections from scratch 566 24.18 Conversions between Java and Scala collections... 568 24.19 Migrating from Scala 2.7. 570 24.20 Conclusion. 571 25 The Architecture of Scala Collections 573 25.1 Builders. 574 25.2 Factoring out common operations 575 25.3 Integrating new collections 580 25.4 Conclusion 596 26 Extractors 597 26.1 An example: extracting email addresses 597 26.2 Extractors 598 26.3 Patterns with zero or one variables 601 26.4 Variable argument extractors 603 26.5 Extractors and sequence patterns 606 26.6 Extractors versus case classes 607 26.7 Regular expressions 608 26.8 Conclusion 612 27 Annotations 613 27.1 Why have annotations? 613 27.2 Syntax of annotations 614 27.3 Standard annotations. 616 xx
27.4 Conclusion 620 28 Working with XML 621 28.1 Semi-structured data 621 28.2 XML overview 622 28.3 XML literals 623 28.4 Serialization 625 28.5 Taking XML apart 627 28.6 Deserialization 628 28.7 Loading and saving 629 28.8 Pattern matching on XML 631 28.9 Conclusion 634 29 Modular Programming Using Objects 635 29.1 The problem 636 29.2 A recipe application 637 29.3 Abstraction 640 29.4 Splitting modules into traits 643 29.5 Runtime linking 646 29.6 Tracking module instances 647 29.7 Conclusion 649 30 Object Equality 651 30.1 Equality in Scala 651 30.2 Writing an equality method 652 30.3 Defining equality for parameterized types 665 30.4 Recipes for equals and hashcode 670 30.5 Conclusion 676 31 Combining Scala and Java 677 31.1 Using Scala from Java 677 31.2 Annotations 680 31.3 Existential types '-.."... 685 31.4 Using synchronized 689 31.5 Compiling Scala and Java together 689 31.6 Conclusion 690 32 Actors and Concurrency 691 xxi
Contents 32.1 Trouble in paradise 691 32.2 Actors and message passing 692 32.3 Treating native threads as actors 696 32.4 Better performance through thread reuse 697 32.5 Good actors style 700 32.6 A longer example: Parallel discrete event simulation.. 707 32.7 Conclusion 724 33 Combinator Parsing 727 33.1 Example: Arithmetic expressions. 728 33.2 Running your parser 730 33.3 Basic regular expression parsers 731 33.4 Another example: JSON 732 33.5 Parser output 734 33.6 Implementing combinator parsers 740 33.7 String literals and regular expressions 749 33.8 Lexing and parsing 750 33.9 Error reporting 750 33.10 Backtracking versus LL(1) 752 33.11 Conclusion 754 34 GUI Programming 757 34.1 A first Swing application 757 34.2 Panels and layouts 760 34.3 Handling events 762 34.4 Example: Celsius/Fahrenheit converter 765 34.5 Conclusion 767 35 The SCells Spreadsheet 769 35.1 The visual framework 769 35.2 Disconnecting data entry and display 772 35.3 Formulas 775 35.4 Parsing formulas 777 35.5 Evaluation 782 35.6 Operation libraries 785 35.7 Change propagation 788 35.8 Conclusion 792 xxii
A Scala Scripts on Unix and Windows 795 Glossary 797 Bibliography 813 About the Authors 817 Index 819 xxm