1. A taste of advanced Scala

  • Methods of a single param can be called with curly braces.
  • Traits with a single method can be used with a lambda.
  • If a method finishes in :, the method is right associative, otherwise it’s left associative.
  • Multi-world method names can be defined with backticks: def and then said(gossip: String)
  • Pattern matching
    • Pattern matching can be applied to any object that implements the unapply method (this is called an extractor object).
    • Custom lists can be decomposed by implementing the unapplySeq method. Thus, we imlement support for variable patterns. def unapply(person: Person): Option[(String, Int)]

2. Advanced FP

  • Partial functions

4.31 Parallel utilities

  • To create a parallel collection: val col = List(1,2,3).par
  • Parallel list operations are much faster on bigger collections.

5. Implicits

  • If a class method doesn’t exist, the compiler will exhaustively look for a matching method that would work after an implicit conversion.
    case class Person(name: String) {
    def greet = s"Hi, my name is $name!"
    }
    implicit def fromStringToPerson(str: String): Person = Person(str)
    println("Peter".greet) // println(fromStringToPerson("Peter"))
    
  • Implicits that are used as implicit parameters can be var, val, object and accessor methods (def with no parens).
  • Implicit scope: normal scope (local scope); imported scope; companion objects of all types involved in the method signature.
  • Best practise: it’s a good idea to define implicit values on companion objects that can be imported as needed.
  • Best practise: keep type enrichment to implict clases and type classes; package implicits clearly, bringing into scope only what you need.