Programming Scala (Lập trình Scala) - Dean Wampler & Alex Payne

LI
lienhejb
0 downloads
591
0

Document content

Page 1

2nd Edition Programming Scala SCALABILITY = FUNCTIONAL PROGRAMMING + OBJECTS Dean Wampler & Alex Payne

Page 2

Programming Scala Get up to speed on Scala, the JVM language that offers all the benefits of Dean Wampler, Ph.D. is the Big Data a modern object model, functional programming, and an advanced type Architect for Typesafe, where he system. Packed with code examples, this comprehensive book shows builds data-centric tools and services, you how to be productive with the language and ecosystem right away, using Scala, functional programming, Spark, Hadoop, and Akka. Dean is the and explains why Scala is ideal for today's highly scalable, data-centric author of Functional Programming applications that support concurrency and distribution. for Java Developers and co-author of This second edition covers recent language features, with new chapters Programming Hive. on pattern matching, comprehensions, and advanced functional Alex Payne is Platform Lead at programming. You’ll also learn about Scala’s command-line tools, third- Twitter, where he develops services that enable programmers to build party tools, libraries, and language-aware plugins for editors and IDEs. This atop the popular social messaging book is ideal for beginning and advanced Scala developers alike. service. Alex has previously built web applications for political campaigns, ■ Program faster with Scala’s succinct and flexible syntax nonprofits, and early-stage startups. ■ Dive into basic and advanced functional programming (FP) techniques ■ Build killer big-data apps, using Scala’s functional combinators ■ Use traits for mixin composition and pattern matching for data extraction ■ Learn the sophisticated type system that combines FP and object-oriented programming concepts ■ Explore Scala-specific concurrency tools, including Akka ■ Understand how to develop rich domain-specific languages ■ Learn good design techniques for building scalable and robust Scala applications The example source code for this book is maintained in a public GitHub repository. SC AL A /JAVA /PROGR AMMING L ANGUAGES Twitter: @oreillymedia facebook.com/oreilly US $49.99 CAN $52.99 ISBN: 978-1-491-94985-6

Page 3

SECOND EDITION Programming Scala Dean Wampler and Alex Payne BeijingBeijing BostonBoston FarnhamFarnham SebastopolSebastopol TokyoTokyo

Page 4

Programming Scala by Dean Wampler and Alex Payne Copyright © 2015 Kevin Dean Wampler and Alex Payne. All rights reserved. Printed in the United States of America. Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472. O’Reilly books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles (http://oreilly.com/safari). For more information, contact our corporate/insti‐ tutional sales department: 800-998-9938 or corporate@oreilly.com. Editor:Meghan Blanchette Indexer:Wendy Catalano Production Editor:Nicole Shelby Interior Designer:David Futato Copyeditor:Kim Cofer Cover Designer:Ellie Volckhausen Proofreader:Charles Roumeliotis Illustrator:Rebecca Demarest September, 2009: First Edition November, 2014: Second Edition Revision History for the Second Edition 2014-11-25: First release 2015-03-27: Second release 2017-08-11: Third release See http://oreilly.com/catalog/errata.csp?isbn=9781491949856 for release details. The O’Reilly logo is a registered trademark of O’Reilly Media, Inc. Programming Scala, the cover image, and related trade dress are trademarks of O’Reilly Media, Inc. While the publisher and the authors have used good faith efforts to ensure that the information and instructions contained in this work are accurate, the publisher and the authors disclaim all responsibility for errors or omissions, including without limitation responsibility for damages resulting from the use of or reliance on this work. Use of the information and instructions contained in this work is at your own risk. If any code samples or other technology this work contains or describes is subject to open source licenses or the intellectual property rights of others, it is your responsibility to ensure that your use thereof complies with such licenses and/or rights. 978-1-491-91949-6 [LSI]

Page 7

Table of Contents Foreword. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv Preface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii 1. Zero to Sixty: Introducing Scala. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Why Scala? 1 The Seductions of Scala 2 What About Java 8? 3 Installing Scala 3 Using SBT 5 Running the Scala Command-Line Tools 6 Running the Scala REPL in IDEs 9 A Taste of Scala 9 A Taste of Concurrency 19 Recap and What’s Next 31 2. Type Less, Do More. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 Semicolons 33 Variable Declarations 34 Ranges 36 Partial Functions 37 Method Declarations 38 Method Default and Named Arguments 39 Methods with Multiple Argument Lists 39 A Taste of Futures 41 Nesting Method Definitions and Recursion 44 Inferring Type Information 46 Reserved Words 51 v

Page 8

Literal Values 54 Integer Literals 54 Floating-Point Literals 55 Boolean Literals 56 Character Literals 56 String Literals 57 Symbol Literals 59 Function Literals 59 Tuple Literals 59 Option, Some, and None: Avoiding nulls 61 Sealed Class Hierarchies 63 Organizing Code in Files and Namespaces 63 Importing Types and Their Members 65 Imports Are Relative 67 Package Objects 67 Abstract Types Versus Parameterized Types 68 Recap and What’s Next 70 3. Rounding Out the Basics. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 Operator Overloading? 71 Syntactic Sugar 74 Methods with Empty Argument Lists 74 Precedence Rules 76 Domain-Specific Languages 77 Scala if Statements 78 Scala for Comprehensions 79 for Loops 79 Generator Expressions 79 Guards: Filtering Values 80 Yielding 80 Expanded Scope and Value Definitions 81 Other Looping Constructs 83 Scala while Loops 83 Scala do-while Loops 84 Conditional Operators 84 Using try, catch, and finally Clauses 85 Call by Name, Call by Value 87 lazy val 91 Enumerations 92 Interpolated Strings 95 Traits: Interfaces and “Mixins” in Scala 97 Recap and What’s Next 99 vi | Table of Contents

Page 9

4. Pattern Matching. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 A Simple Match 101 Values, Variables, and Types in Matches 102 Matching on Sequences 106 Matching on Tuples 110 Guards in case Clauses 111 Matching on case Classes 111 unapply Method 113 unapplySeq Method 117 Matching on Variable Argument Lists 119 Matching on Regular Expressions 120 More on Binding Variables in case Clauses 121 More on Type Matching 122 Sealed Hierarchies and Exhaustive Matches 123 Other Uses of Pattern Matching 126 Concluding Remarks on Pattern Matching 130 Recap and What’s Next 130 5. Implicits. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 Implicit Arguments 131 Using implicitly 133 Scenarios for Implicit Arguments 134 Execution Contexts 134 Capabilities 135 Constraining Allowed Instances 135 Implicit Evidence 140 Working Around Erasure 142 Improving Error Messages 144 Phantom Types 145 Rules for Implicit Arguments 148 Implicit Conversions 149 Build Your Own String Interpolator 153 The Expression Problem 155 Type Class Pattern 156 Technical Issues with Implicits 158 Implicit Resolution Rules 160 Scala’s Built-in Implicits 161 Wise Use of Implicits 168 Recap and What’s Next 168 6. Functional Programming in Scala. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 What Is Functional Programming? 170 Table of Contents | vii

Page 10

Functions in Mathematics 170 Variables That Aren’t 171 Functional Programming in Scala 174 Anonymous Functions, Lambdas, and Closures 175 Purity Inside Versus Outside 178 Recursion 178 Tail Calls and Tail-Call Optimization 179 Trampoline for Tail Calls 181 Partially Applied Functions Versus Partial Functions 182 Currying and Other Transformations on Functions 183 Functional Data Structures 187 Sequences 188 Maps 192 Sets 194 Traversing, Mapping, Filtering, Folding, and Reducing 195 Traversal 195 Mapping 196 Flat Mapping 199 Filtering 200 Folding and Reducing 201 Left Versus Right Traversals 206 Tail Recursion Versus Traversals of Infinite Collections 209 Combinators: Software’s Best Component Abstractions 213 What About Making Copies? 216 Recap and What’s Next 218 7. for Comprehensions in Depth. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221 Recap: The Elements of for Comprehensions 221 for Comprehensions: Under the Hood 224 Translation Rules of for Comprehensions 227 Options and Other Container Types 230 Option as a Container 230 Either: A Logical Extension to Option 234 Try: When There Is No Do 239 Scalaz Validation 240 Recap and What’s Next 243 8. Object-Oriented Programming in Scala. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 Class and Object Basics 246 Reference Versus Value Types 248 Value Classes 250 Parent Types 253 viii | Table of Contents

Page 11

Constructors in Scala 254 Fields in Classes 258 The Uniform Access Principle 260 Unary Methods 261 Validating Input 262 Calling Parent Class Constructors (and Good Object-Oriented Design) 264 Good Object-Oriented Design: A Digression 265 Nested Types 269 Recap and What’s Next 271 9. Traits. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273 Interfaces in Java 8 273 Traits as Mixins 274 Stackable Traits 279 Constructing Traits 284 Class or Trait? 286 Recap and What’s Next 286 10. The Scala Object System, Part I. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287 Parameterized Types: Variance Under Inheritance 287 Functions Under the Hood 288 Variance of Mutable Types 292 Variance in Scala Versus Java 295 The Scala Type Hierarchy 296 Much Ado About Nothing (and Null) 297 Products, Case Classes, and Tuples 302 The Predef Object 303 Implicit Conversions 304 Type Definitions 306 Condition Checking Methods 307 Input and Output Methods 308 Miscellaneous Methods 310 Equality of Objects 310 The equals Method 311 The == and != Methods 311 The eq and ne Methods 312 Array Equality and the sameElements Method 313 Recap and What’s Next 313 11. The Scala Object System, Part II. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315 Overriding Members of Classes and Traits 315 Avoid Overriding Concrete Members 316 Table of Contents | ix

Page 12

Attempting to Override final Declarations 318 Overriding Abstract and Concrete Methods 319 Overriding Abstract and Concrete Fields 321 Overriding Abstract Types 328 When Accessor Methods and Fields Are Indistinguishable: The Uniform Access Principle 329 Linearization of an Object’s Hierarchy 331 Recap and What’s Next 336 12. The Scala Collections Library. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337 Generic, Mutable, Immutable, Concurrent, and Parallel Collections, Oh My! 337 The scala.collection Package 338 The collection.concurrent Package 340 The collection.convert Package 340 The collection.generic Package 340 The collection.immutable Package 340 The scala.collection.mutable Package 341 The scala.collection.parallel Package 343 Choosing a Collection 344 Design Idioms in the Collections Library 345 Builder 345 CanBuildFrom 346 Like Traits 348 Specialization for Value Types 348 Miniboxing 350 Recap and What’s Next 350 13. Visibility Rules. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353 Public Visibility: The Default 353 Visibility Keywords 354 Public Visibility 355 Protected Visibility 356 Private Visibility 357 Scoped Private and Protected Visibility 359 Final Thoughts on Visibility 365 Recap and What’s Next 366 14. Scala’s Type System, Part I. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367 Parameterized Types 368 Variance Annotations 368 Type Constructors 368 Type Parameter Names 369 x | Table of Contents

Page 13

Type Bounds 369 Upper Type Bounds 369 Lower Type Bounds 370 Context Bounds 374 View Bounds 375 Understanding Abstract Types 377 Comparing Abstract Types and Parameterized Types 378 Self-Type Annotations 381 Structural Types 386 Compound Types 389 Type Refinements 390 Existential Types 391 Recap and What’s Next 392 15. Scala’s Type System, Part II. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393 Path-Dependent Types 393 C.this 394 C.super 394 path.x 395 Dependent Method Types 396 Type Projections 397 Singleton Types 399 Types for Values 400 Tuple Types 400 Function Types 401 Infix Types 401 Higher-Kinded Types 402 Type Lambdas 406 Self-Recursive Types: F-Bounded Polymorphism 408 Recap and What’s Next 410 16. Advanced Functional Programming. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411 Algebraic Data Types 411 Sum Types Versus Product Types 411 Properties of Algebraic Data Types 413 Final Thought on Algebraic Data Types 414 Category Theory 414 About Categories 415 The Functor Category 416 The Monad Category 421 The Importance of Monad 423 Recap and What’s Next 424 Table of Contents | xi

Page 14

17. Tools for Concurrency. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427 The scala.sys.process Package 427 Futures 429 Async 432 Robust, Scalable Concurrency with Actors 434 Akka: Actors for Scala 434 Actors: Final Thoughts 446 Pickling and Spores 447 Reactive Programming 447 Recap and What’s Next 449 18. Scala for Big Data. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451 Big Data: A Brief History 451 Improving MapReduce with Scala 453 Moving Beyond MapReduce 458 Categories for Mathematics 460 A List of Scala-Based Data Tools 460 Recap and What’s Next 461 19. Dynamic Invocation in Scala. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463 A Motivating Example: ActiveRecord in Ruby on Rails 463 Dynamic Invocation in Scala with the Dynamic Trait 464 DSL Considerations 469 Recap and What’s Next 469 20. Domain-SpecificLanguages in Scala. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471 Examples: XML and JSON DSLs for Scala 472 Internal DSLs 474 External DSLs with Parser Combinators 479 About Parser Combinators 479 A Payroll External DSL 479 Internal Versus External DSLs: Final Thoughts 482 Recap and What’s Next 483 21. Scala Tools and Libraries. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485 Command-Line Tools 485 scalac Command-Line Tool 485 The scala Command-Line Tool 489 The scalap and javap Command-Line Tools 492 The scaladoc Command-Line Tool 493 The fsc Command-Line Tool 494 Build Tools 494 xii | Table of Contents

Page 15

SBT, the Standard Build Tool for Scala 494 Other Build Tools 496 Integration with IDEs and Text Editors 497 Text Editors 498 Test-Driven Development in Scala 498 Third-Party Libraries 499 Recap and What’s Next 501 22. Java Interoperability. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503 Using Java Names in Scala Code 503 Java and Scala Generics 503 JavaBean Properties 506 AnyVal Types and Java Primitives 507 Scala Names in Java Code 507 Recap and What’s Next 507 23. Application Design. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509 Recap of What We Already Know 509 Annotations 510 Traits as Modules 514 Design Patterns 516 Creational Patterns 516 Structural Patterns 517 Behavioral Patterns 518 Better Design with Design by Contract 520 The Parthenon Architecture 522 Recap and What’s Next 528 24. Metaprogramming: Macros andReflection. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 529 Tools for Understanding Types 530 Runtime Reflection 530 Reflecting on Types 531 Class Tags, Type Tags, and Manifests 532 Scala’s Advanced Runtime Reflection API 533 Macros 537 A Macro Example: Enforcing Invariants 539 Final Thoughts on Macros 542 Wrapping Up and Looking Ahead 543 A. References. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545 Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 551 Table of Contents | xiii

Page 17

Foreword If there has been a common theme throughout my career as a programmer, it has been the quest for better abstractions and better tools to support the craft of writing software. Over the years, I have come to value one trait more than any other: com‐ posability. If one can write code with good composability, it usually means that other traits we software developers value—such as orthogonality, loose coupling, and high cohesion—are already present. It is all connected. When I discovered Scala some years ago, the thing that made the biggest impression on me was its composability. Through some very elegant design choices and simple yet powerful abstractions that were taken from the object-oriented and functional programming worlds, Martin Odersky has managed to create a language with high cohesion and orthogonal, deep abstractions that invites composability in all dimensions of software design. Scala is truly a SCAlable LAnguage that scales with usage, from scripting all the way up to large-scale enterprise applications and middleware. Scala was born out of academia, but it has grown into a pragmatic and practical lan‐ guage that is very much ready for real-world production use. What excites me most about this book is that it’s so practical. Dean has done a fantas‐ tic job, not only by explaining the language through interesting discussions and sam‐ ples, but also by putting it in the context of the real world. It’s written for the programmer who wants to get things done. I had the pleasure of getting to know Dean some years ago when we were both part of the aspect-oriented programming community. Dean holds a rare mix of deep analyti‐ cal academic thinking and a pragmatic, get-things-done kind of mentality. You are about to learn how to write reusable components using mixin and function composition; how to write Reactive applications using Akka; how to make effective use of advanced features in Scala such as macros and higher kinded types; how to uti‐ lize Scala’s rich, flexible, and expressive syntax to build domain-specific languages; xv

Page 18

how to effectively test your Scala code; how to let Scala simplify your Big Data prob‐ lems; and much, much more. Enjoy the ride. I sure did. — Jonas Bonér CTO & cofounder Typesafe August 2014 xvi | Foreword

Page 19

Preface Programming Scala introduces an exciting and powerful language that offers all the benefits of a modern object model, functional programming (FP), and an advanced type system, while leveraging the industry’s investment in the Java Virtual Machine (JVM). Packed with code examples, this comprehensive book teaches you how to be productive with Scala quickly, and explains what makes this language ideal for today’s scalable, distributed, component-based applications that support concurrency and distribution. You’ll also learn how Scala takes advantage of the advanced JVM as a platform for programming languages. Learn more at http://programming-scala.org or at the book’s catalog page. Welcome to Programming Scala, Second Edition Programming Scala, First Edition was published five years ago, in the fall of 2009. At the time, it was only the third book dedicated to Scala, and it just missed being the second by a few months. Scala version 2.7.5 was the official release, with version 2.8.0 nearing completion. A lot has changed since then. At the time of this writing, the Scala version is 2.11.2. Martin Odersky, the creator of Scala, and Jonas Bonér, the creator of Akka, an actor- based concurrency framework, cofounded Typesafe to promote the language and tools built on it. There are also a lot more books about Scala. So, do we really need a second edition of this book? Many excellent beginner’s guides to Scala are now available. A few advanced books have emerged. The encyclopedic reference remains Programming in Scala, Second Edition, by Odersky et al. (Artima Press). Yet, I believe Programming Scala, Second Edition remains unique because it is a com‐ prehensive guide to the Scala language and ecosystem, a guide for beginners to advanced users, and it retains the focus on the pragmatic concerns of working profes‐ sionals. These characteristics made the first edition popular. xvii

Page 20

Scala is now used by many more organizations than in 2009 and most Java developers have now heard of Scala. Several persistent questions have emerged. Isn’t Scala com‐ plex? Since Java 8 added significant new features found in Scala, why should I switch to Scala? I’ll tackle these and other, real-world concerns. I have often said that I was seduced by Scala, warts and all. I hope you’ll feel the same way after reading Programming Scala, Second Edition. How to Read This Book Because this is a comprehensive book, beginning readers don’t need to read the whole thing to be productive with Scala. The first three chapters, Zero to Sixty: Introducing Scala, Type Less, Do More, and Rounding Out the Basics, provide a quick summary of core language features. The fourth and fifth chapters, Pattern Matching and Implicits, begin the more in-depth coverage with two fundamental tools that you’ll use every day in your Scala code. If you’re new to functional programming (FP), Chapter 6 provides an introduction to this important approach to software development, as implemented in Scala. Next is Chapter 7, which explains Scala’s extensions to the venerable for loop and how it pro‐ vides a succinct syntax for sophisticated, idiomatic functional code. Then we turn to Scala’s support for object-oriented programming (OOP) in Chapter 8. I put the FP chapter before the OOP chapters to emphasize the importance of FP in solving many software development problems of our time. It would be easy to use Scala as a “better object-oriented Java,” but that would ignore its most powerful tools! Most of this chapter will be conceptually easy to understand, as you learn how Scala defines classes, constructors, etc. that are familiar in Java. Chapter 9 explores Scala’s ability to compose behaviors using traits. Java 8 adds a sub‐ set of this functionality through its enhancements to interfaces, partially inspired by Scala traits. Even experienced Java programmers will need to understand this mate‐ rial. The next four chapters, 10 through 13, The Scala Object System, Part I, The Scala Object System, Part II, The Scala Collections Library, and Visibility Rules, walk through Scala’s object model and library types in detail. You should read Chapter 10 carefully, because it contains essential information to master early on. However, Chapter 11 goes into less critical information, the details of properly implementing nontrivial type hierarchies. You might skim that chapter the first time through the book. Chap‐ ter 12 discusses the design of the collections and some useful information about using them wisely. Again, skim this chapter if you’re new to Scala and come back to it when you’re trying to master the details of the collections API. Finally, Chapter 13 explains xviii | Preface

Showing the first 20 pages. Download the document to see it all.

Comments (0)

Sign in to join the discussion

No comments yet. Be the first!