Note:
This blog is intended to record what I learned in Functional Program Design in Scala, rather than share the course materials. So there are two things that I won’t put up: my solution to assignments and topics which I’ve mastered already.
PLEASE NOTIFY ME if I broke Coursera Honor Code accidentally.

## Week 1

### Lecture 1.1 - Queries with For

• the for notation is essentially equivalent to the common operations of query languages for databases.

### Lecture 1.2 - Translation of For

• the Scala compiler translates for-expressions in terms of map, flatMap and a lazy variant of filter.

• we can use for syntax for our own types as long as we define map, flatMap and withFilter for these types.

### Lecture 1.3 - Functional Random Generators

• we can use self => at the begining of class/trait body to declare an alias for this.

• define a trait Generator[T] that generates random values of type T:

• how can we avoid the new Generator boilerplate since it’s not trivial? Use for syntax:

• some helper functions:

• [Exercise] how to implement a generator that creates random Tree objects?

• random test: generate random test inputs.

• a monad is a parametric type M[T] with two operations: flatMap (in the literature, flatMap is more commonly called bind) and unit, that have to satisfy some laws:

• List is a monad with unit(x) = List(x); Set is monad with unit(x) = Set(x); Generator is a monad with unit(x) = single(x)

• map can be defined for every monad as a combination of flatMap and unit:

• to qualify as a monad, a type has to satisfy three laws:

• associativity:

• left unit:

• right unit:

• [Note] you might find List doesn’t obey the left unit rule since List(1) flatMap (Set(_)) = List(1) != Set(1), this is because the monad law assumes f: A => M[A] (here f: A => List[A]). Refer to link.

• what is the significance of the laws with respect to for syntax?

• associativity says essentially that one can “inline” nested for expressions:

• right unit says:

• left unit does not have an analogue for for-expressions.

• Try is not a monad since it breaks the left unit rule:
• Try(expr) flatMap f != f(expr): left-hand side will never raise a non-fatal exception whereas the right-hand side will raise any exception thrown by expr or f.
• Try trades one monad law for another law which is more useful in this context:
• an expression composed from Try, map, flatMap will never throw a non-fatal exception.

## Week 2

### Lecture 2.2 - Streams

• streams is similar to lists, but their tail is evaluated only on demand.

• we use #:: instead of :: for stream prepending.

• how to use stream to improve efficiency?

### Lecture 2.3 - Lazy Evaluation

• in a purely functional language an expression produces the same result each time it is evaluated.
• lazy evaluation means evaluting on first demand, storing the result of the first evaluation and re-using the stored result instead of recomputing.
• it’s not by-name evaluation where everything is recomputed.
• it’s not restricted evaluation for normal parameters and val definitions.
• Haskell use lazy evaluation by default, but Scala use stricted evaluation by default since it also supports mutable side effects (which might be inharmonious with lazy evaluation) in functions.

### Lecture 2.4 - Computing with Infinite Sequences

• define an infinity stream:

• calculate all prime numbers:

• calculate the square root:

### Lecture 2.5 - Case Study: the Water Pouring Problem

• a very decent solution to Water Pouring Problem, which is quite worthy of being reviewed.
• some guiding principles for good design:
• name everything you can.
• put operations into natural scopes.
• keep degrees of freedom for future refinements.

## Week 3

### Lecture 3.2 - Identity and Change

• the precise meaning of “being the same” is defined by the property of operational equivalence.
• x and y are operationally equivalent if no possible test can distinguish between them.

### Lecture 3.3 - Loops

• for-loops is not for-expression (end with yield).
• for-loops translate similarly to for-expression, but using foreach combinator instead of map and flatMap.

## Week 4

### Lecture 4.1 - Imperative Event Handling: The Observer Pattern

• the Observer Pattern is widely used when views need to react to changes in a model. Variants of it are also called:
• publish/subscribe.
• mode/view/controller (MVC).

### Lecture 4.2 - Functional Reactive Programming

• imperative reactive programming is about reacting to sequences of events that happen in time, while in functional view: aggregate an event sequence into a signal.
• generally, an indexted argument like f(E1,...,En) = E is translated to f.update(E1,...,En, E), which also works if n = 0.
• sig.update(5) can be abbreviated to sig() = 5.
• we cannot update signal value by s() = s() + 1, since this statement tries to define a signal to be at all points in time one larger than itself.

### Lecture 4.7 - Combinators on Futures 2

• do not block when you have asynchronous computation.

## Conclusions

### How to Apply Functional Design Elements in Applications

• lazy evaluation and infinite data structures
• distinction between computations and values (e.g. a random value acctually is a computation).
• monads to abstract over properties of computation (randomness, delays, effects).
• running computations at some later time.