This repository is the online hub for the book Hands-on Scala Programming:
-
Chapter Notes, Errata, and Discussion: go here if you want to leave comments or ask questions about individual chapters
-
Code Snippets: copy-paste friendly versions of every code snippet in the book
-
Chapter Resource Files: files used as part of the book's programming exercises
-
Executable Code Examples: self-contained executable programs for the topics being presented in each chapter.
The executable code examples from Hands-on Scala are freely available online, and open source under an MIT license. Each example is:
-
Self-contained: to be run either using the Ammonite script runner or Mill build tool, with no other setup
-
Tested: with simple test suites provided and instructions on how to run each example in that folder's
readme.md
file -
Executable: you can download the folder and run the example yourself to see it in action
Many of the examples are related, with only small code changes between them to
illustrate a new feature or technique. The readme.md
file of such downstream
examples will show a diff from the upstream example that it was based upon, so
you can focus your attention on the important code changes that are happening,
with a link back up to the upstream example.
The executable code examples below are organized by each part and each chapter of the book.
- 6.1 - MergeSort: Simple merge-sort implemention, hard-coded to only work on
Array[Int]
- 6.2 - GenericMergeSort: Generic merge sort implemention, that can sort any
IndexedSeq[T]
with anOrdering
- 6.3 - Trie: A simple mutable Trie implemention
- 6.4 - Search: Breadth-first-search implemention
- 6.5 - SearchPaths: Breadth-first-search implemention that keeps track of the shortest paths to every node
- 6.6 - BinarySearch: Binary search implementation
- 6.7 - ImmutableTrie: Immutable trie implementation
- 6.8 - DepthSearchPaths: Depth-first search implementation that keeps track of shortest paths
- 7.1 - LargestFiles: Script to finds the largest 5 files in the current folder tree
- 7.2 - FileSync: Method to batch synchronize files between two local folders
- 7.3 - RemoveBranches: Script to remove all non-active branches from the local Git repository
- 7.4 - InteractivePython: Example of how to interact with a running Python process from Scala
- 7.5 - StreamingDownloadProcessReupload1: Three-stage streaming subprocess pipeline
- 7.6 - StreamingDownloadProcessReupload2: Four-stage streaming subprocess pipeline
- 7.7 - FileSyncDelete: Method to synchronize files between two folders, with support for deletion
- 7.8 - StreamingDownloadProcessReuploadTee: Five stage subprocess pipeline,
tee
d streaming data to a file
- 8.1 - Create: Parsing JSON structures from strings and constructing it directly
- 8.2 - Manipulate: Querying and modifying JSON structures in-memory
- 8.3 - Traverse: Recursively traversing a JSON structure
- 8.4 - SerializationBuiltins: Serializing built-in Scala data types to JSON
- 8.5 - SerializationCaseClass: Serializing Scala case classes to JSON
- 8.6 - SerializationBinary: Serializing Scala data types to binary MessagePack blobs
- 8.7 - BiMapClass: Using
bimap
to make a non-case class serializable
- 9.1 - Printing: Listing blog-post-like files in a folder and printing them out
- 9.2 - Index: Rendering an
index.html
for our static blog using Scalatags - 9.3 - Markdown: Rendering individual blog posts using Atlassian's Commonmark-Java library
- 9.4 - Links: Adding links between our
index.html
and the individual blog posts - 9.5 - Bootstrap: Prettifying our static blog using the Bootstrap CSS framework
- 9.6 - Deploy: Optionally deploying our static blog to a Git repository
- 9.7 - DeployTimestamp: Displaying the
.md
file last-modified time on each blog post
- 10.1 - Simple: Simple linear build pipeline
- 10.2 - Nonlinear: Simple non-linear build pipeline with two branches
- 10.3 - Modules: Simple non-linear build pipeline, replicated in several modules
- 10.4 - NestedModules: Nested modules in a Mill build pipeline
- 10.5 - CrossModules: Using cross-modules to dynamically construct a build graph based on the filesystem
- 10.6 - Blog: Our static blog generator, converted into an incremental Mill build pipeline
- 10.7 - ExtendedBlog: Adding previews and bundled Bootstrap CSS to our static blog build pipeline
- 10.8 - Push: Re-adding the ability to deploy our static blog by defining a
T.command
- 11.1 - ScrapingWiki: Scraping headlines off the Wikipedia front page using Jsoup
- 11.2 - ScrapingDocs: Scraping semi-structured content off of the Mozilla Development Network Web API docs
- 11.3 - ApiStatus: Using Jsoup to scrape the status annotations for every Web API on MDN
- 11.4 - ExternalLinks: Crawling the pages of a static website to extract every external link on the site
- 12.1 - IssueMigrator: Simple Github issue migrator
- 12.2 - IssueMigratorLink: Github issue migrator that adds a link back from every new issue to the original issue
- 12.3 - IssueMigratorClosed: Github issue migrator that also preserves issue open/closed status during the migration
- 13.1 - Hashing: Hashing files in parallel using Futures
- 13.2 - Crawler: Simple sequential wikipedia crawler
- 13.3 - ParallelCrawler: Simple batch-by-batch parallel wikipedia crawler, using Futures and Requests-Scala
- 13.4 - RecursiveCrawler: Parallel wikipedia crawler written in a recursive fashion
- 13.5 - AsyncCrawler: Asynchronous parallel wikipedia crawler, using the Java AsyncHttpClient
- 13.6 - ParallelScrapingDocs: Scraping MDN Web API documentation pages in parallel using Futures
- 13.7 - ParallelMergeSort: Merge-sort implementation parallelized using Futures
- 13.8 - AsyncCrawlerThrottled: Asynchronous wikipedia crawler which limits the number of open requests
- 13.9 - AsyncThottledScrapingDocs: Asynchronous parallel MDN scraper that limits the number of open requests
- 14.1 - Mock: Dummy non-interactive HTML chat website and server
- 14.2 - Forms: Form-based interactive chat website
- 14.3 - Ajax: Ajax-based interactive chat website
- 14.4 - Websockets: Websocket-based real-time chat website
- 14.5 - WebsocketsFilter: Websocket-based chat website with ability to filter chats
- 14.6 - WebsocketsSynchronized: Websocket-based chat website with shared mutable state properly synchronized
- 14.7 - WebsocketsJsoup: Websocket-based chat website with HTML validation tests using Jsoup
- 15.1 - Queries: Simple Quill database queries
- 15.2 - Website: Database-backed websocket chat website
- 15.3 - FancyQueries: Fancier Quill database queries with
groupBy
andsortBy
- 15.4 - WebsiteTimestamps: Database-backed websocket chat website with timestamps on every chat message
- 16.1 - Simple: Simple logging actor that asynchronously uploads log messages to httpbin.org servers
- 16.2 - Batch: Batch logging actor that uploads batches of log messages to httpbin.org servers
- 16.3 - StateMachine: Actor that uploads batches of logs to httpbin.org, with a minimum interval between each batch
- 16.4 - LoggingSimple: Logging actor that asynchronously logs messages to disk
- 16.5 - LoggingPipeline: Two-stage logging actor pipeline that asynchronously logs base64-encoded messages to disk
- 16.6 - LoggingLongPipeline: Four-actor pipeline that logs sanitized, base64-encoded messages both to disk and to
httpbin.org
- 16.7 - LoggingRearrangedPipeline1: Three-actor logging pipeline without sanitization
- 16.8 - LoggingRearrangedPipeline2: Four-actor pipeline, with only disk logs base64-encoded and only
httpbin.org
uploads sanitized - 16.9 - WebCrawler: A concurrent actor-based web crawler that avoids the limitations of earlier batch-by-batch crawlers
- 16.10 - WebCrawlerPipeline: A concurrent actor-based web crawler that streams the crawled pages to disk
- 16.11 - WebCrawlerThrottled: A concurrent actor-based web crawler that limits the number of open connections
- 17.1 - FileSyncer: Simple two-process batch file synchronizer that could work over a network
- 17.2 - Pipelined: Pipelined version of our two-process file synchronizer, minimizing the chattiness of the protocol
- 17.3 - Deletes: Pipelined two-process file synchronizer that supports deletions
- 18.1 - Simple: Simple real-time file synchronizer that uses
os.watch
to react to filesystem changes as they happen - 18.2 - Pipelined: Pipelined real-time file synchronizer, allowing RPCs and hashing to take place in parallel
- 18.3 - InitialFiles: Real-time file synchronizer that supports syncing an initial set of files
- 18.4 - ForkJoinHashing: Real-time file synchronizer that does hashing of files in parallel
- 19.1 - Phrases: Parser for simple "hello world"-like phrases
- 19.2 - Arithmetic: Parser and evaluator for simple english-like arithmetic expressions
- 19.3 - ArithmeticChained: English-like arithmetic parser, allowing more than one binary operator to be chained together
- 19.4 - ArithmeticPrecedence: English-like arithmetic parser, supporting operator precedence of chained binary operators
- 19.5 - ArithmeticDirect: English-like arithmetic parser that evaluates the arithmetic without constructing a syntax tree
- 20.1 - Jsonnet: Interpreter for a minimal subset of the Jsonnet programming language
- 20.2 - JsonnetNumbers: Jsonnet interpreter with added support for simple integer arithmetic
- 20.3 - JsonnetPrettyPrinting: Jsonnet interpreter using the uJson library for pretty-printing the output JSON