- Many functional programmers feel that short names make code easier to read, since it makes the structure of the code easier to see at a glance. (loc. 771-72)
- So we can state plainly what a monad is: A monad is an implementation of one of the minimal sets of monadic combinators, satisfying the laws of associativity and identity. That’s a perfectly respectable, precise, and terse definition. And if we’re being precise, this is the only correct definition. A monad is precisely defined by its operations and laws; no more, no less. But it’s a little unsatisfying. It doesn’t say much about what it implies—what a monad means. (loc. 4778-82)
- We could say that monads provide a context for introducing and binding variables, and performing variable substitution. (loc. 4805-6)
- Monads provide a powerful interface, as evidenced by the fact that we can use flatMap to essentially write imperative programs in a purely functional way. (loc. 4903-4)
- Applicative constructs context-free computations, while Monad allows for context sensitivity. (loc. 5019-20)
- Functors are a less expressive but more compositional generalization of monads. The functions unit and map allow us to lift values and functions, whereas map2 and apply give us the power to lift functions of higher arities. (loc. 5384-85)
- The insight here is that inside every function with side effects is a pure function waiting to get out. (loc. 5441-42)
- As far as we’re concerned, a program is just a referentially transparent expression—a pure computation that may occasionally make requests of some interpreter. The interpreter is free to use side effects or not. That’s now an entirely separate concern. (loc. 5837-39)
- This brings us to an essential point: tracking effects is a choice we make as programmers. It’s a value judgement, and there are trade-offs associated with how we choose. We can take it as far as we want. But as with the context of referential transparency, in Scala there’s a kind of standard choice. For example, it would be completely valid and possible to track memory allocations in the type system if that really mattered to us. But in Scala we have the benefit of automatic memory management, so the cost of explicit tracking is usually higher than the benefit. (loc. 6261-65)