Skip to content

Programming in Scala

Resources

Introductory book for scala.

Modules

Chapter Checklist

  • 1 A Scalable Language
    • 1.1 A language that grows on you
    • 1.2 What makes Scala scalable?
    • 1.3 Why Scala?
    • 1.4 Scala’s roots
    • 1.5 Conclusion
  • 2 First Steps in Scala
    • Step 1. Learn to use the Scala interpreter
    • Step 2. Define some variables
    • Step 3. Define some functions
    • Step 4. Write some Scala scripts
    • Step 5. Loop with while; decide with if
    • Step 6. Iterate with foreach and for
    • Conclusion
  • 3 Next Steps in Scala
    • Step 7. Parameterize arrays with types
    • Step 8. Use lists
    • Step 9. Use tuples
    • Step 10. Use sets and maps
    • Step 11. Learn to recognize the functional style
    • Step 12. Read lines from a file
    • Conclusion
  • 4 Classes and Objects
    • 4.1 Classes, fields, and methods
    • 4.2 Semicolon inference
    • 4.3 Singleton objects
    • 4.4 A Scala application
    • 4.5 The Application trait
    • 4.6 Conclusion
  • 5 Basic Types and Operations
    • 5.1 Some basic types
    • 5.2 Literals
    • 5.3 Operators are methods
    • 5.4 Arithmetic operations
    • 5.5 Relational and logical operations
    • 5.6 Bitwise operations
    • 5.7 Object equality
    • 5.8 Operator precedence and associativity
    • 5.9 Rich wrappers
    • 5.10 Conclusion
  • 6 Functional Objects
    • 6.1 A specification for class Rational
    • 6.2 Constructing a Rational
    • 6.3 Reimplementing the toString method
    • 6.4 Checking preconditions
    • 6.5 Adding fields
    • 6.6 Self references
    • 6.7 Auxiliary constructors
    • 6.8 Private fields and methods
    • 6.9 Defining operators
    • 6.10 Identifiers in Scala
    • 6.11 Method overloading
    • 6.12 Implicit conversions
    • 6.13 A word of caution
    • 6.14 Conclusion
  • 7 Built-in Control Structures
    • 7.1 If expressions
    • 7.2 While loops
    • 7.3 For expressions
    • 7.4 Exception handling with try expressions
    • 7.5 Match expressions
    • 7.6 Living without break and continue
    • 7.7 Variable scope
    • 7.8 Refactoring imperative-style code
    • 7.9 Conclusion
  • 8 Functions and Closures
    • 8.1 Methods
    • 8.2 Local functions
    • 8.3 First-class functions
    • 8.4 Short forms of function literals
    • 8.5 Placeholder syntax
    • 8.6 Partially applied functions
    • 8.7 Closures
    • 8.8 Repeated parameters
    • 8.9 Tail recursion
    • 8.10 Conclusion
  • 9 Control Abstraction
    • 9.1 Reducing code duplication
    • 9.2 Simplifying client code
    • 9.3 Currying
    • 9.4 Writing new control structures
    • 9.5 By-name parameters
    • 9.6 Conclusion
  • 10 Composition and Inheritance
    • 10.1 A two-dimensional layout library
    • 10.2 Abstract classes
    • 10.3 Defining parameterless methods
    • 10.4 Extending classes
    • 10.5 Overriding methods and fields
    • 10.6 Defining parametric fields
    • 10.7 Invoking superclass constructors
    • 10.8 Using override modifiers
    • 10.9 Polymorphism and dynamic binding
    • 10.10 Declaring final members
    • 10.11 Using composition and inheritance
    • 10.12 Implementing above, beside, and toString
    • 10.13 Defining a factory object
    • 10.14 Heighten and widen
    • 10.15 Putting it all together
    • 10.16 Conclusion
  • 11 Scala’s Hierarchy
    • 11.1 Scala’s class hierarchy
    • 11.2 How primitives are implemented
    • 11.3 Bottom types
    • 11.4 Conclusion
  • 12 Traits
    • 12.1 How traits work
    • 12.2 Thin versus rich interfaces
    • 12.3 Example: Rectangular objects
    • 12.4 The Ordered trait
    • 12.5 Traits as stackable modifications
    • 12.6 Why not multiple inheritance?
    • 12.7 To trait, or not to trait?
    • 12.8 Conclusion
  • 13 Packages and Imports
    • 13.1 Packages
    • 13.2 Imports
    • 13.3 Implicit imports
    • 13.4 Access modifiers
    • 13.5 Conclusion
  • 14 Assertions and Unit Testing
    • 14.1 Assertions
    • 14.2 Unit testing in Scala
    • 14.3 Informative failure reports
    • 14.4 Using JUnit and TestNG
    • 14.5 Tests as specifications
    • 14.6 Property-based testing
    • 14.7 Organizing and running tests
    • 14.8 Conclusion
  • 15 Case Classes and Pattern Matching
    • 15.1 A simple example
    • 15.2 Kinds of patterns
    • 15.3 Pattern guards
    • 15.4 Pattern overlaps
    • 15.5 Sealed classes
    • 15.6 The Option type
    • 15.7 Patterns everywhere
    • 15.8 A larger example
    • 15.9 Conclusion
  • 16 Working with Lists
    • 16.1 List literals
    • 16.2 The List type
    • 16.3 Constructing lists
    • 16.4 Basic operations on lists
    • 16.5 List patterns
    • 16.6 First-order methods on class List
    • 16.7 Higher-order methods on class List
    • 16.8 Methods of the List object
    • 16.9 Understanding Scala’s type inference algorithm
    • 16.10 Conclusion
  • 17 Collections
    • 17.1 Overview of the library
    • 17.2 Sequences
    • 17.3 Sets and maps
    • 17.4 Selecting mutable versus immutable collections
    • 17.5 Initializing collections
    • 17.6 Tuples
    • 17.7 Conclusion
  • 18 Stateful Objects
    • 18.1 What makes an object stateful?
    • 18.2 Reassignable variables and properties
    • 18.3 Case study: Discrete event simulation
    • 18.4 A language for digital circuits
    • 18.5 The Simulation API
    • 18.6 Circuit Simulation
    • 18.7 Conclusion
  • 19 Type Parameterization
    • 19.1 Functional queues
    • 19.2 Information hiding
    • 19.3 Variance annotations
    • 19.4 Checking variance annotations
    • 19.5 Lower bounds
    • 19.6 Contravariance
    • 19.7 Object private data
    • 19.8 Upper bounds
    • 19.9 Conclusion
  • 20 Abstract Members
    • 20.1 A quick tour of abstract members
    • 20.2 Type members
    • 20.3 Abstract vals
    • 20.4 Abstract vars
    • 20.5 Initializing abstract vals
    • 20.6 Abstract types
    • 20.7 Path-dependent types
    • 20.8 Enumerations
    • 20.9 Case study: Currencies
    • 20.10 Conclusion
  • 21 Implicit Conversions and Parameters
    • 21.1 Implicit conversions
    • 21.2 Rules for implicits
    • 21.3 Implicit conversion to an expected type
    • 21.4 Converting the receiver
    • 21.5 Implicit parameters
    • 21.6 View bounds
    • 21.7 Debugging implicits
    • 21.8 Conclusion
  • 22 Implementing Lists
    • 22.1 The List class in principle
    • 22.2 The ListBuffer class
    • 22.3 The List class in practice
    • 22.4 Functional on the outside
    • 22.5 Conclusion
  • 23 For Expressions Revisited
    • 23.1 For expressions
    • 23.2 The n-queens problem
    • 23.3 Querying with for expressions
    • 23.4 Translation of for expressions
    • 23.5 Going the other way
    • 23.6 Generalizing for
    • 23.7 Conclusion
  • 24 Extractors
    • 24.1 An example: Extracting email addresses
    • 24.2 Extractors
    • 24.3 Patterns with zero or one variables
    • 24.4 Variable argument extractors
    • 24.5 Extractors and sequence patterns
    • 24.6 Extractors versus case classes
    • 24.7 Regular expressions
    • 24.8 Conclusion
  • 25 Annotations
    • 25.1 Why have annotations?
    • 25.2 Syntax of annotations
    • 25.3 Standard annotations
    • 25.4 Conclusion
  • 26 Working with XML
    • 26.1 Semi-structured data
    • 26.2 XML overview
    • 26.3 XML literals
    • 26.4 Serialization
    • 26.5 Taking XML apart
    • 26.6 Deserialization
    • 26.7 Loading and saving
    • 26.8 Pattern matching on XML
    • 26.9 Conclusion
  • 27 Modular Programming Using Objects
    • 27.1 The problem
    • 27.2 A recipe application
    • 27.3 Abstraction
    • 27.4 Splitting modules into traits
    • 27.5 Runtime linking
    • 27.6 Tracking module instances
    • 27.7 Conclusion
  • 28 Object Equality
    • 28.1 Equality in Scala
    • 28.2 Writing an equality method
    • 28.3 Defining equality for parameterized types
    • 28.4 Recipes for equals and hashCode
    • 28.5 Conclusion
  • 29 Combining Scala and Java
    • 29.1 Using Scala from Java
    • 29.2 Annotations
    • 29.3 Existential types
    • 29.4 Conclusion
  • 30 Actors and Concurrency
    • 30.1 Trouble in paradise
    • 30.2 Actors and message passing
    • 30.3 Treating native threads as actors
    • 30.4 Better performance through thread reuse
    • 30.5 Good actors style
    • 30.6 A longer example: Parallel discrete event simulation
    • 30.7 Conclusion
  • 31 Combinator Parsing
    • 31.1 Example: Arithmetic expressions
    • 31.2 Running your parser
    • 31.3 Basic regular expression parsers
    • 31.4 Another example: JSON
    • 31.5 Parser output
    • 31.6 Implementing combinator parsers
    • 31.7 String literals and regular expressions
    • 31.8 Lexing and parsing
    • 31.9 Error reporting
    • 31.10 Backtracking versus LL(1)
    • 31.11 Conclusion
  • 32 GUI Programming
    • 32.1 A first Swing application
    • 32.2 Panels and layouts
    • 32.3 Handling events
    • 32.4 Example: Celsius/Fahrenheit converter
    • 32.5 Conclusion
  • 33 The SCells Spreadsheet
    • 33.1 The visual framework
    • 33.2 Disconnecting data entry and display
    • 33.3 Formulas
    • 33.4 Parsing formulas
    • 33.5 Evaluation
    • 33.6 Operation libraries
    • 33.7 Change propagation
    • 33.8 Conclusion