Study note of the chapter 23, 26, 27 of the book: Programming In Scala, 4th Edition.

## Chapter 23 For Expression Revisisted

For expression syntax is `for (seq) yield expr` where `seq` is a sequence of generator, defintions and filters. A generator is is of the form `pat <- expr`, if the pattern matches, the variables in the pattern get bound to the element parts. If the match failes, the element is discarded from the iteration.

The translation of for expressions is as the following:

• `for (x <- expr1) yield expr2`: `expr1.map(x => expr2)`
• `for (x <- expr1 if expr2) yield expr3`: `expr1.withFilter(x => expr2) yield expr3`
• `for (x <- expr1 if expr2; seq) yield expr3`: `for(expr1.withFilter(x => expr2; seq) yield expr3`
• `for (x <- expr1; y<-expr2; seq) yield expr3`: `expr1.flatMap(x => for (y <- expr2; seq>) yield expr3)`
• `for (x <- expr1; y = expr2; seq) yield expr3`: `for((x, y) <- for (x <- expr1) yield (x, expr2); seq) yield expr3`
• `for(x <- expr1) body`: `expr1 foreach (x => body)`
• `for(x <- expr1, if expr2) body`: `expr1 withFilter(x => expr2) foreach (x => body)`

Rules for generalizing `for`

• If just define `map`, it allows single generator.
• If define `map` and `flatMap`, it allows multiple generator.
• If define `foreach`, it allows `for` loop.
• If define `withFilter`, it allows `if` in the `for` expression.

## Chapter 26 Extractors

An `extractor` is an object that defines an `unapply` method that matches a value and take it apart. The `apply` method of an object is called an `injection` because it takes some arguments and creates an elemnt of a give type. The `unapply` method is called an `extraction` because it takes an elmeent into parts. They are dual to each other.

The `unaplly` method may return a `Some` of a tuple that has two or more elements, or `Some(x)` for one variable, or `Boolean` for empty variable. Use `Some(Seq[T])` for `vararg` matching (`_*` in pattern).

Unlike case classes that bind a type to a pattern, the extractor enables `representation independence`.

Use `Regex` or `.r` postfix to define a regular expression. Each expression is also an extractor that is used to identify substrings that are matched by the groups of the regular expression.

## Chapter 27 Annontation

`Annotations` are structured information added to program source code. They are used by `meta-programming` tools. Scala compiles understands annotations but leaves them to individual tools to process them. Commonly used annotations:

• `@deprecated`
• `@unchecked`
• `@volatile`
• `@SerialVersionUID` used with `Serializable` trait
• `@transient` for not-serializable fields
• `@tailrec` for tail-recursive methods.
• `@native`: JNI interface

## Chapter 29 Modular Programming Using Objects

Use objects for modules. Use classes for module templates (interfaces). Use traits to split modules into separate files.

Use `self type` to specify that a trait is to be mixed with another type.

Because nested classes are path dependent, use `singleton type` syntax `a.type` to help compiler.

## Chpater 32 Futures and Concurrency

Future is Scala’s solution for concurrency: it allows a series of asynchronous transformations of immutable state represetned by `Future`. It avoids shared memory and locks. For backcompatibility, Scala support `wait`, `notify`, `notfiyAll` and `synchronized`.

### 32.1 Execution Context and Trys

`Future` represents a computation to be performed asynchronously. Many operations on `Future` also executed in a different thread. Both `Future` and many of its operations require an implicit `ExecutionContext`. Scala provides one `scala.concurrent.ExxecutionContext.Implicits.global`.

The result has a type of `Some[Try[T]]`. When `isCompleted` is false, the result is `None`. Otherwise, the `value` method returns an `Success[T]` for a success and `Failure[T]` for a failure.

### 32.2 Operarions

• Run an async operation
• `Future(expr)`: the `apply` method.
• Transformation
• `map`: returns a new future that asynchronously transforms the orginal asynchronously computed result.
• `for` expression: `for` serializes its transformation. Futures created inside `for` expression are execuited sequentially.
• `flatten`: falts a `[Future[Future[T]]]` value into a `[Future[T]]` value.
• Creation: create already completed futures, doesn’t need `ExecutionContext`
• `Future.successful`: a `Success[T]`
• `Future.failed`: a `Failure[Throwable]`
• `Future.fromTry`: a `Success[T]` or a `Failure[Throwable]` based on the argument
• `Promise`: first create a `Promise[T]`, then call its `success(value)` or `failure(exception)` method, `complete(tryValule)`, or `completeWith(aFuture)`. Use `future` to get the created future object.
• Filtering a `Future` object
• `filter`: if future is failed, the `filter` is ignore. If future is succeeded, if the filter is satisfied, return the success value, otherwise, return an exeption.
• `withFilter`: used in `for` expression
• `collect partialFunction`: filter and transofrm.
• Dealing with failure
• `failed`: returns a new future that flips the failure and success
• `fallbackTo`: an alternate future to use in case of the orginal future fails.
• `recover partialFunction`: recover with a value when there is a match for failed result
• `recoverWith partialFunctoin`: recover with a new future when there is a match for failed result
• `transform(res => ???, ex => ???)`: handle both success and failure. The pattern can be a `Try` mapped toanther `Try` that allows you to control the success or failure.
• `transformWith()`: transform a future using `Try => Future` function.
• Combine Futures
• `zip`: transform two successful futures into a future tuple of both values. If there is a failure, first failure returns.
• `zipWith`: zip and transform
• `Future.foldLeft`/`Future.reduceLeft`: accumulates a ressult across an `Iterable` collection of futures.
• `Future.sequnce`: transforms a `TraversableOnce` collection of futures into a future `TraversableOnce` of values.
• `Future.traverse`: transforms a `TraversableOnce` of any element type to a `TraversableOnce` of future of `TraversableOnce` of values.
• Performing side-effects

• `foreach`: perform a side effect on success, nothing on failure. Also support the `for` loop syntax
• `onComplete { case Success(res) => ???; case Failure(ex) => ???}`
• `andThen { case Success(res) => ???; case Failure(ex) => ???}`: can control the order of `andThen` callbacks.

### 32.3 Testing With Futures

`Await.result` watis for value synchornously.

`ScalaFuture` trait adds a `futureValue` to a future.

Scalatest introduces `AsyncFunSpec`.

The pattern is staying asynchronously by performing a series of transformations. To get results out of future space, register side effects to be performed asynchronously once futures complete.