Hands-on Scala Programming: Learn Scala in a Practical, Project-Based Way
by Haoyi Li
- Length: 414 pages
- Edition: 1
- Language: English
- Publisher: Li Haoyi
- Publication Date: 2020-07-11
- ISBN-10: 9811456933
- ISBN-13: 9789811456930
- Sales Rank: #418715 (See Top 100 Books)
Hands-on Scala teaches you how to use the Scala programming language in a practical, project-based fashion. This book is designed to quickly teach an existing programmer everything needed to go from “hello world” to building production applications like interactive websites, parallel web crawlers, and distributed systems in Scala. In the process you will learn how to use the Scala language to solve challenging problems in an elegant and intuitive manner.
Table of Contents Foreword Author's Note Part I: Introduction to Scala 1 Hands-on Scala 1.1 Why Scala? 1.1.1 A Compiled Language that feels Dynamic 1.1.2 Easy Safety and Correctness 1.1.3 A Broad and Deep Ecosystem 1.2 Why This Book? 1.2.1 Beyond the Scala Language 1.2.2 Focused on Real Projects 1.2.3 Code First 1.3 How This Book Is Organized 1.3.1 Chapter Dependency Graph 1.4 Code Snippet and Examples 1.4.1 Command-Line Snippets 1.4.2 Scala REPL Snippets 1.4.3 Source Files 1.4.4 Diffs 1.5 Online Materials 1.5.1 Code Snippets 1.5.2 Executable Code Examples 1.5.3 Exercises 1.5.4 Resources 1.5.5 Online Discussion 1.6 Conclusion 2 Setting Up 2.1 Windows Setup (Optional) 2.2 Installing Java 2.3 Installing Ammonite 2.3.1 The Scala REPL 2.3.2 Scala Scripts 2.3.2.1 Watching Scripts 2.3.3 Using Scripts from the REPL 2.4 Installing Mill 2.4.1 Mill Projects 2.4.2 Running Unit Tests 2.4.3 Creating a Stand-Alone Executable 2.5 IDE Support 2.5.1 Installing IntelliJ for Scala 2.5.2 Integrating IntelliJ with Mill 2.5.3 Visual Studio Code Support 2.6 Conclusion 3 Basic Scala 3.1 Values 3.1.1 Primitives 3.1.2 Strings 3.1.3 Local Values and Variables 3.1.4 Tuples 3.1.5 Arrays 3.1.6 Options 3.2 Loops, Conditionals, Comprehensions 3.2.1 For-Loops 3.2.2 If-Else 3.2.3 Fizzbuzz 3.2.4 Comprehensions 3.3 Methods and Functions 3.3.1 Methods 3.3.1.1 Returning Values from Methods 3.3.2 Function Values 3.3.2.1 Methods taking Functions 3.3.2.2 Multiple Parameter Lists 3.4 Classes and Traits 3.4.1 Traits 3.5 Conclusion 4 Scala Collections 4.1 Operations 4.1.1 Builders 4.1.2 Factory Methods 4.1.3 Transforms 4.1.4 Queries 4.1.5 Aggregations 4.1.5.1 mkString 4.1.5.2 foldLeft 4.1.5.3 groupBy 4.1.6 Combining Operations 4.1.7 Converters 4.1.8 Views 4.2 Immutable Collections 4.2.1 Immutable Vectors 4.2.2 Structural Sharing 4.2.3 Immutable Sets 4.2.4 Immutable Maps 4.2.5 Immutable Lists 4.3 Mutable Collections 4.3.1 Mutable ArrayDeques 4.3.2 Mutable Sets 4.3.3 Mutable Maps 4.3.4 In-Place Operations 4.4 Common Interfaces 4.5 Conclusion 5 Notable Scala Features 5.1 Case Classes and Sealed Traits 5.1.1 Case Classes 5.1.2 Sealed Traits 5.1.3 Use Cases for Normal v.s. Sealed Traits 5.2 Pattern Matching 5.2.1 Match 5.2.1.1 Matching on 5.2.1.2 Matching on 5.2.1.3 Matching on tuple 5.2.1.4 Matching on tuple 5.2.2 Nested Matches 5.2.1.5 Matching on Case Classes: 5.2.1.6 Matching on String Patterns: 5.2.3 Loops and Vals 5.2.4 Pattern Matching on Sealed Traits and Case Classes 5.2.4.1 Stringifying Our Expressions 5.2.4.2 Evaluating Our Expressions 5.3 By-Name Parameters 5.3.1 Avoiding Evaluation 5.3.2 Wrapping Evaluation 5.3.3 Repeating Evaluation 5.4 Implicit Parameters 5.4.1 Passing ExecutionContext to Futures 5.4.2 Dependency Injection via Implicits 5.5 Typeclass Inference 5.5.1 Problem Statement: Parsing Command Line Arguments 5.5.2 Separate Parser Objects 5.5.2.1 Re-Using Our StrParsers 5.5.3 Solution: Implicit StrParser 5.5.3.1 Re-Using Our Implicit StrParsers 5.5.3.2 Context-Bound Syntax 5.5.3.3 Compile-Time Implicit Safety 5.5.4 Recursive Typeclass Inference 5.5.4.1 Parsing Sequences 5.5.4.2 Parsing Tuples 5.5.4.3 Parsing Nested Structures 5.6 Conclusion Part II: Local Development 6 Implementing Algorithms in Scala 6.1 Merge Sort 6.1.1 Generic Merge Sort 6.2 Prefix Tries 6.2.1 Trie Set Operations 6.2.1.1 Trie.add 6.2.1.2 Trie.contains 6.2.2 Trie Prefix Operations 6.2.2.1 Trie.prefixesMatchingString 6.2.2.2 Trie.stringsMatchingPrefix 6.3 Breadth First Search 6.3.1 Implementing Breadth First Search 6.4 Shortest Paths 6.5 Conclusion 7 Files and Subprocesses 7.1 Paths 7.1.1 Constructing Paths 7.1.2 Relative Paths 7.1.3 Sub Paths 7.2 Filesystem Operations 7.2.1 Queries 7.2.1.1 os.list 7.2.1.2 os.walk 7.2.1.3 os.stat 7.2.2 Actions 7.2.2.1 os.read, os.write 7.2.2.2 os.move 7.2.2.3 os.copy 7.2.2.4 os.remove 7.2.2.5 os.makeDir 7.2.3 Combining Operations 7.2.4 Streaming 7.2.5 Transforming Streams 7.3 Folder Syncing 7.3.1 Walking the Filesystem 7.3.2 Copying New Files Over 7.3.3 Updating Files 7.3.4 Testing Our File Syncer 7.4 Simple Subprocess Invocations 7.4.1 Use Case: remove non-current branches from a Git repo 7.4.2 Use Case: Curl to a local file 7.4.3 Streaming Gzip 7.5 Interactive and Streaming Subprocesses 7.5.1 Interacting with a Subprocess 7.5.2 Streaming distinct contributors in a Git repo history 7.5.3 Streaming Subprocess Pipelines 7.6 Conclusion 8 JSON and Binary Data Serialization 8.1 Manipulating JSON 8.1.1 The ujson.Value Data Type 8.1.2 Querying and Modifying JSON 8.1.3 Extracting Typed Values 8.1.4 Traversing JSON 8.2 JSON Serialization of Scala Data Types 8.2.1 Serializing Scala Builtins 8.2.2 Serializing Case Classes 8.2.3 Mapped Serializers 8.3 Writing your own Generic Serialization Methods 8.3.1 uPickle Context Bounds 8.3.2 Generic Serialization Methods 8.3.3 Why Context Bounds? 8.3.3.1 Performance with Convenience 8.3.3.2 Compile-Time Error Reporting 8.3.3.3 Security 8.4 Binary Serialization 8.4.1 writeBinary and readBinary 8.4.2 MessagePack Structures 8.5 Conclusion 9 Self-Contained Scala Scripts 9.1 Reading Files Off Disk 9.2 Rendering HTML with Scalatags 9.3 Rendering Markdown with Commonmark-Java 9.3.1 Translating Java Snippets to Scala 9.3.2 Testing our Java Markdown Parser 9.4 Links and Bootstrap 9.4.1 Page Links 9.4.2 Bootstrap 9.5 Optionally Deploying the Static Site 9.6 Conclusion 10 Static Build Pipelines 10.1 Mill Build Pipelines 10.1.1 Defining a Build Pipeline 10.1.1.1 Targets 10.1.1.2 Target Destination Folders 10.1.2 Using Your Build Pipeline 10.1.3 Non-linear Build Pipelines 10.1.4 Incremental Re-Computation 10.2 Mill Modules 10.2.1 Nested Modules 10.2.2 Cross Modules 10.2.3 Modules Based on Folder Layout 10.3 Revisiting our Static Site Script 10.4 Conversion to a Mill Build Pipeline 10.4.1 For-Loop to Cross Modules 10.4.2 An Index Page Target 10.4.3 Arranging Files For Distribution 10.4.4 Using Your Static Build Pipeline 10.5 Extending our Static Site Pipeline 10.5.1 Bundling Bootstrap 10.5.2 Post Previews 10.5.3 A Complete Static Site Pipeline 10.6 Conclusion Part III: Web Services 11 Scraping Websites 11.1 Scraping Wikipedia 11.1.1 Selection 11.1.2 CSS Selector Cheat Sheet 11.1.3 Choosing Selectors via Inspect Element 11.1.4 Extracting data 11.2 MDN Web Documentation 11.3 Scraping MDN 11.3.1 Scraping The Documentation Index 11.3.2 Scraping Each Documentation Page 11.3.2.1 Finding the First Paragraph 11.3.2.2 Finding Property and Method Docs 11.4 Putting it Together 11.5 Conclusion 12 Working with HTTP APIs 12.1 The Task: Github Issue Migrator 12.1.1 Old Existing Repository 12.1.2 Brand New Repository 12.2 Creating Issues and Comments 12.3 Fetching Issues and Comments 12.3.1 Pagination 12.3.2 Picking the data we want 12.3.3 Issue Comments 12.4 Migrating Issues and Comments 12.4.1 One new issue per old issue 12.4.2 One new comment per old comment 12.5 Conclusion 13 Fork-Join Parallelism with Futures 13.1 Parallel Computation using Futures 13.1.1 Sequential Code 13.1.2 Spawning Futures 13.1.3 Offloading Work from the Main Thread 13.2 N-Ways Parallelism 13.2.1 N Sequential Computations 13.2.2 N Parallel Computations 13.2.3 Futures vs Threads 13.3 Parallel Web Crawling 13.3.1 A Single HTTP Request 13.3.2 Sequential Crawling 13.3.3 Parallel Crawling 13.3.4 Testing our Parallel Webcrawler 13.3.5 Thread Pool and Parallelism Limits 13.4 Asynchronous Futures 13.4.1 Futures and Promises 13.4.2 Interfacing with Callbacks using Promises 13.4.2.1 Converting Futures to Callbacks 13.4.2.2 Converting Callbacks to Futures 13.4.3 Asynchronous Operators 13.4.3.1 map, foreach 13.4.3.2 zip 13.4.3.3 sequence 13.5 Asynchronous Web Crawling 13.5.1 Web Crawling via Recursion 13.5.2 Asynchronous Link Fetching with AsyncHttpClient 13.5.3 Asynchronous Recursive Web Crawling 13.6 Conclusion 14 Simple Web and API Servers 14.1 A Minimal Webserver 14.1.1 Application Code 14.1.2 Webserver Build Configuration 14.1.3 Running and Testing our Webserver 14.2 Serving HTML 14.2.1 A Mock Chat Website 14.3 Forms and Dynamic Data 14.3.1 Dynamic Page Rendering 14.3.2 Form Handling 14.3.3 Validation 14.3.4 Remembering Names and Messages 14.4 Dynamic Page Updates via API Requests 14.4.1 Rendering Partial Pages 14.4.2 Page Updates with JavaScript 14.5 Real-time Updates with Websockets 14.5.1 Server-side Websocket Support 14.5.2 Browser-side Websocket Support 14.6 Conclusion 15 Querying SQL Databases 15.1 Setting up Quill and PostgreSQL 15.1.1 Library Setup 15.1.2 Sample Data 15.1.3 PG-CLI 15.2 Mapping Tables to Case Classes 15.3 Querying and Updating Data 15.3.1 Filtering 15.3.2 Lifting 15.3.3 Mapping 15.3.4 Joins 15.3.5 Inserts 15.3.6 Updates 15.4 Transactions 15.4.1 Why Transactions? 15.5 A Database-Backed Chat Website 15.5.1 Build Config & Database Setup 15.5.2 Storing Messages in the Database 15.5.3 Testing our Database-backed Website 15.6 Conclusion Part IV: Program Design 16 Message-based Parallelism with Actors 16.1 Castor Actors 16.1.1 Actor Classes 16.1.1.1 SimpleActor 16.1.1.2 BatchActor 16.1.1.3 StateMachineActor 16.1.2 Contexts, Exceptions, and State 16.2 Actor-based Background Uploads 16.2.1 Simple Upload Actor 16.2.2 Actors vs Futures 16.2.2.1 Streaming vs Request-Response 16.2.2.2 Preserving Ordering 16.2.2.3 Private Mutable State 16.2.3 Batch Upload Actor 16.2.4 State Machine Upload Actor 16.3 Concurrent Logging Pipelines 16.3.1 A Logging SimpleActor 16.3.2 Multi-stage Actor Pipelines 16.3.3 Non-Linear Pipelines 16.3.4 Re-arranging Actor Pipelines 16.4 Debugging Actors 16.4.1 Debug Logging State Machines 16.4.2 Running Actors Single Threaded 16.4.3 Debugging using Context Logging 16.5 Conclusion 17 Multi-Process Applications 17.1 Two-Process Build Setup 17.1.1 Integrating our Simple File Syncer into Mill 17.1.2 Testing our File Syncer 17.2 Remote Procedure Calls 17.2.1 Defining our RPC Messages 17.2.2 Bytes over the Wire 17.3 The Agent Process 17.4 The Sync Process 17.4.1 Spawning the Agent 17.4.2 Delegating File Operations 17.5 Pipelined Syncing 17.5.1 Pipelining RPCs 17.5.2 Batching Pipelined Filesystem Operations 17.6 Conclusion 18 Building a Real-time File Synchronizer 18.1 Watching for Changes 18.2 Real-time Syncing with Actors 18.2.1 Architecture 18.2.2 Build Configuration 18.2.3 Shared Code 18.2.4 Agent 18.2.5 Sync 18.2.5.1 Initializing the Agent 18.2.5.2 SyncActor Messages 18.2.5.3 SyncActor 18.2.5.4 agentReader and os.watch 18.3 Testing the Syncer 18.4 Pipelined Real-time Syncing 18.4.1 Pipelined Architecture 18.4.2 Pipelined Implementation 18.5 Testing the Pipelined Syncer 18.6 Conclusion 19 Parsing Structured Text 19.1 Simple Parsers 19.1.1 Partial & Incomplete Parses 19.1.2 Alternative Parsers 19.1.3 Sequence Parsers 19.1.4 Combining Alternatives with Sequences 19.1.5 Repeated Parsers 19.1.6 Optional Parsers 19.2 Parsing Structured Values 19.2.1 Capturing Strings 19.2.2 Parsing Case Classes 19.2.3 Modularizing and Typing our Parsers 19.2.4 Using Sub-Parsers Independently 19.2.5 Recursive Parsers 19.3 Implementing a Calculator 19.3.1 Defining our Syntax Tree 19.3.2 Parsing Literals 19.3.3 Parsing Arithmetic 19.3.4 Manipulating the Syntax Tree 19.4 Parser Debugging and Error Reporting 19.4.1 Debugging Parsers via .log 19.4.1.1 Adding Logs 19.4.1.2 Logging a Successful Parse 19.4.1.3 Logging a Failed Parse 19.4.2 Error Reporting with Cuts 19.4.2.1 Minimal Example: No Cuts 19.4.2.2 Minimal Example: Cuts 19.4.2.3 Arithmetic Parser Cuts 19.5 Conclusion 20 Implementing a Programming Language 20.1 Interpreting Jsonnet 20.2 Jsonnet Language Features 20.2.1 Primitives 20.2.2 Locals and Functions 20.2.3 Composition 20.3 Parsing Jsonnet 20.3.1 Defining the Syntax Tree 20.3.2 Example Parses 20.3.2.1 Strings 20.3.2.2 Dictionaries 20.3.2.3 Functions 20.3.2.4 Locals 20.3.3 Parsing Terminals 20.3.3.1 Parsing Strings 20.3.3.2 Parsing Identifiers 20.3.4 Parsing Plus 20.3.4.1 Constructing Parse Nodes with Fold Left 20.3.5 Parsing Dictionaries 20.3.6 Completing the Parser 20.3.7 Testing the Parser 20.4 Evaluating the Syntax Tree 20.4.1 Expr vs Value 20.4.2 Defining Evaluate 20.4.3 Evaluating Literals 20.4.4 Evaluating Plus 20.4.5 Evaluating Locals and Identifiers 20.4.5.1 Evaluating Locals 20.4.5.2 Evaluating Identifiers 20.4.6 Evaluating Functions 20.4.6.1 Evaluating Function Calls 20.4.6.2 Evaluating Function Definitions 20.5 Serializing to JSON 20.5.1 Complete Jsonnet Interpreter 20.6 Conclusion Conclusion
Donate to keep this site alive
To access the Link, solve the captcha.
1. Disable the AdBlock plugin. Otherwise, you may not get any links.
2. Solve the CAPTCHA.
3. Click download link.
4. Lead to download server to download.