From 2d41ed08badfee61976d30e1255f3108c1902620 Mon Sep 17 00:00:00 2001 From: Marko Schulz Date: Sun, 11 Feb 2018 08:55:18 +0100 Subject: [PATCH] Unify the headings capitalisation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the Chicago Manual of Style. Used https://marketplace.visualstudio.com/items?itemName=zkirkland.vscode-firstupper#overview for it and manually checked the results afterwards (the extension wanted to capitalise the “n'” in “Types n' Types” but this seems wrong, since it is an abbreviation of “and”.) --- CONTRIBUTING.md | 2 +- SUMMARY.md | 58 ++++++++++++++++++++++++------------------------- ch01.md | 4 ++-- ch02.md | 4 ++-- ch03.md | 10 ++++----- ch04.md | 12 +++++----- ch05.md | 4 ++-- ch06.md | 4 ++-- ch07.md | 10 ++++----- ch08.md | 6 ++--- ch09.md | 4 ++-- ch10.md | 6 ++--- ch12.md | 2 +- 13 files changed, 63 insertions(+), 63 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c66e447c..fde84ebb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,7 +20,7 @@ explain yourself. Translations to other languages are highly encouraged. Each official translation will be held as a separate repository in the [MostlyAdequate organization](https://github.com/MostlyAdequate) and linked from the English version book. Since each translation is a different repository, we can also have different maintainers for each project. -### Creating a new translation repo +### Creating a New Translation Repo In order to create a new translation, you need to follow these steps: diff --git a/SUMMARY.md b/SUMMARY.md index 58d9fd02..2437834d 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -1,49 +1,49 @@ # Summary -* [Chapter 01: What ever are we doing?](ch01.md) +* [Chapter 01: What Ever Are We Doing?](ch01.md) * [Introductions](ch01.md#introductions) - * [A brief encounter](ch01.md#a-brief-encounter) + * [A Brief Encounter](ch01.md#a-brief-encounter) * [Chapter 02: First Class Functions](ch02.md) - * [A quick review](ch02.md#a-quick-review) - * [Why favor first class?](ch02.md#why-favor-first-class) + * [A Quick Review](ch02.md#a-quick-review) + * [Why Favor First Class?](ch02.md#why-favor-first-class) * [Chapter 03: Pure Happiness with Pure Functions](ch03.md) - * [Oh to be pure again](ch03.md#oh-to-be-pure-again) - * [Side effects may include...](ch03.md#side-effects-may-include) - * [8th grade math](ch03.md#8th-grade-math) - * [The case for purity](ch03.md#the-case-for-purity) + * [Oh to Be Pure Again](ch03.md#oh-to-be-pure-again) + * [Side Effects May Include...](ch03.md#side-effects-may-include) + * [8th Grade Math](ch03.md#8th-grade-math) + * [The Case for Purity](ch03.md#the-case-for-purity) * [In Summary](ch03.md#in-summary) * [Chapter 04: Currying](ch04.md) - * [Can't live if livin' is without you](ch04.md#cant-live-if-livin-is-without-you) - * [More than a pun / special sauce](ch04.md#more-than-a-pun--special-sauce) - * [In summary](ch04.md#in-summary) + * [Can't Live If Livin' Is without You](ch04.md#cant-live-if-livin-is-without-you) + * [More Than a Pun / Special Sauce](ch04.md#more-than-a-pun--special-sauce) + * [In Summary](ch04.md#in-summary) * [Exercises](ch04.md#exercises) * [Chapter 05: Coding by Composing](ch05.md) - * [Functional husbandry](ch05.md#functional-husbandry) + * [Functional Husbandry](ch05.md#functional-husbandry) * [Pointfree](ch05.md#pointfree) * [Debugging](ch05.md#debugging) - * [Category theory](ch05.md#category-theory) + * [Category Theory](ch05.md#category-theory) * [In Summary](ch05.md#in-summary) * [Exercises](ch05.md#exercises) * [Chapter 06: Example Application](ch06.md) - * [Declarative coding](ch06.md#declarative-coding) - * [A flickr of functional programming](ch06.md#a-flickr-of-functional-programming) + * [Declarative Coding](ch06.md#declarative-coding) + * [A Flickr of Functional Programming](ch06.md#a-flickr-of-functional-programming) * [A Principled Refactor](ch06.md#a-principled-refactor) * [In Summary](ch06.md#in-summary) -* [Chapter 07: Hindley-Milner and Me](ch07.md) - * [What's your type?](ch07.md#whats-your-type) - * [Tales from the cryptic](ch07.md#tales-from-the-cryptic) - * [Narrowing the possibility](ch07.md#narrowing-the-possibility) - * [Free as in theorem](ch07.md#free-as-in-theorem) +* [Chapter 07: Hindley-milner and Me](ch07.md) + * [What's Your Type?](ch07.md#whats-your-type) + * [Tales from the Cryptic](ch07.md#tales-from-the-cryptic) + * [Narrowing the Possibility](ch07.md#narrowing-the-possibility) + * [Free as in Theorem](ch07.md#free-as-in-theorem) * [Constraints](ch07.md#constraints) * [In Summary](ch07.md#in-summary) * [Chapter 08: Tupperware](ch08.md) * [The Mighty Container](ch08.md#the-mighty-container) * [My First Functor](ch08.md#my-first-functor) * [Schrödinger's Maybe](ch08.md#schrödingers-maybe) - * [Use cases](ch08.md#use-cases) - * [Releasing the value](ch08.md#releasing-the-value) + * [Use Cases](ch08.md#use-cases) + * [Releasing the Value](ch08.md#releasing-the-value) * [Pure Error Handling](ch08.md#pure-error-handling) - * [Old McDonald had Effects...](ch08.md#old-mcdonald-had-effects) + * [Old McDonald Had Effects...](ch08.md#old-mcdonald-had-effects) * [Asynchronous Tasks](ch08.md#asynchronous-tasks) * [A Spot of Theory](ch08.md#a-spot-of-theory) * [In Summary](ch08.md#in-summary) @@ -51,18 +51,18 @@ * [Chapter 09: Monadic Onions](ch09.md) * [Pointy Functor Factory](ch09.md#pointy-functor-factory) * [Mixing Metaphors](ch09.md#mixing-metaphors) - * [My chain hits my chest](ch09.md#my-chain-hits-my-chest) - * [Power trip](ch09.md#power-trip) + * [My Chain Hits My Chest](ch09.md#my-chain-hits-my-chest) + * [Power Trip](ch09.md#power-trip) * [Theory](ch09.md#theory) * [In Summary](ch09.md#in-summary) * [Exercises](ch09.md#exercises) * [Chapter 10: Applicative Functors](ch10.md) * [Applying Applicatives](ch10.md#applying-applicatives) - * [Ships in bottles](ch10.md#ships-in-bottles) + * [Ships in Bottles](ch10.md#ships-in-bottles) * [Coordination Motivation](ch10.md#coordination-motivation) - * [Bro, do you even lift?](ch10.md#bro-do-you-even-lift) + * [Bro, Do You Even Lift?](ch10.md#bro-do-you-even-lift) * [Operators](ch10.md#operators) - * [Free can openers](ch10.md#free-can-openers) + * [Free Can Openers](ch10.md#free-can-openers) * [Laws](ch10.md#laws) * [In Summary](ch10.md#in-summary) * [Exercises](ch10.md#exercises) @@ -82,7 +82,7 @@ * [Type Feng Shui](ch12.md#type-feng-shui) * [Effect Assortment](ch12.md#effect-assortment) * [Waltz of the Types](ch12.md#waltz-of-the-types) - * [No Law And Order](ch12.md#no-law-and-order) + * [No Law and Order](ch12.md#no-law-and-order) * [In Summary](ch12.md#in-summary) * [Exercises](ch12.md#exercises) * [Appendix A: Essential Functions Support](appendix_a.md) diff --git a/ch01.md b/ch01.md index d7df9798..cc1d5a6e 100644 --- a/ch01.md +++ b/ch01.md @@ -1,4 +1,4 @@ -# Chapter 01: What ever are we doing? +# Chapter 01: What Ever Are We Doing? ## Introductions @@ -14,7 +14,7 @@ I won't belabor you by listing each and every guideline I've heard throughout th -## A brief encounter +## A Brief Encounter Let's start with a touch of insanity. Here is a seagull application. When flocks conjoin they become a larger flock, and when they breed, they increase by the number of seagulls with whom they're breeding. Now, this is not intended to be good Object-Oriented code, mind you, it is here to highlight the perils of our modern, assignment based approach. Behold: diff --git a/ch02.md b/ch02.md index 2ddb6542..6294b5b4 100644 --- a/ch02.md +++ b/ch02.md @@ -1,6 +1,6 @@ # Chapter 02: First Class Functions -## A quick review +## A Quick Review When we say functions are "first class", we mean they are just like everyone else... so in other words a normal class. We can treat functions like any other data type and there is nothing particularly special about them - they may be stored in arrays, passed around as function parameters, assigned to variables, and what have you. That is JavaScript 101, but worth mentioning since a quick code search on github will reveal the collective evasion, or perhaps widespread ignorance of this concept. Shall we go for a feigned example? We shall. @@ -81,7 +81,7 @@ const BlogController = { ... or scrap it altogether since it does nothing more than just bundle our Views and Db together. -## Why favor first class? +## Why Favor First Class? Okay, let's get down to the reasons to favor first class functions. As we saw in the `getServerStuff` and `BlogController` examples, it's easy to add layers of indirection that provide no added value and only increase the amount of redundant code to maintain and search through. diff --git a/ch03.md b/ch03.md index f59a4e87..fd6a3763 100644 --- a/ch03.md +++ b/ch03.md @@ -1,6 +1,6 @@ # Chapter 03: Pure Happiness with Pure Functions -## Oh to be pure again +## Oh to Be Pure Again One thing we need to get straight is the idea of a pure function. @@ -53,7 +53,7 @@ Its pure form, on the other hand, is completely self sufficient. We can also ma const immutableState = Object.freeze({ minimum: 21 }); ``` -## Side effects may include... +## Side Effects May Include... Let's look more at these "side effects" to improve our intuition. So what is this undoubtedly nefarious *side effect* mentioned in the definition of *pure function*? We'll be referring to *effect* as anything that occurs in our computation other than the calculation of a result. @@ -80,7 +80,7 @@ Side effects disqualify a function from being *pure*. And it makes sense: pure f Let's take a closer look at why we insist on the same output per input. Pop your collars, we're going to look at some 8th grade math. -## 8th grade math +## 8th Grade Math From mathisfun.com: @@ -133,7 +133,7 @@ Of course, you might want to calculate instead of hand writing things out, but t Here comes the dramatic reveal: Pure functions *are* mathematical functions and they're what functional programming is all about. Programming with these little angels can provide huge benefits. Let's look at some reasons why we're willing to go to great lengths to preserve purity. -## The case for purity +## The Case for Purity ### Cacheable @@ -177,7 +177,7 @@ Our `memoize` function works just fine, though it doesn't cache the results of t This is not very useful yet, but we'll soon learn some tricks that will make it so. The takeaway is that we can cache every function no matter how destructive they seem. -### Portable / Self-Documenting +### Portable / Self-documenting Pure functions are completely self contained. Everything the function needs is handed to it on a silver platter. Ponder this for a moment... How might this be beneficial? For starters, a function's dependencies are explicit and therefore easier to see and understand - no funny business going on under the hood. diff --git a/ch04.md b/ch04.md index 9555062f..129d571f 100644 --- a/ch04.md +++ b/ch04.md @@ -1,6 +1,6 @@ # Chapter 04: Currying -## Can't live if livin' is without you +## Can't Live If Livin' Is without You My Dad once explained how there are certain things one can live without until one acquires them. A microwave is one such thing. Smart phones, another. The older folks among us will remember a fulfilling life sans internet. For me, currying is on this list. The concept is simple: You can call a function with fewer arguments than it expects. It returns a function that takes the remaining arguments. @@ -56,7 +56,7 @@ https://github.com/MostlyAdequate/mostly-adequate-guide.git`), copy the code abo go at it in the REPL. The curry function (and actually anything defined in the appendixes) has been made available from the `exercises/support.js` module. -## More than a pun / special sauce +## More Than a Pun / Special Sauce Currying is useful for many things. We can make new functions just by giving our base functions some arguments as seen in `hasSpaces`, `findSpaces`, and `censored`. @@ -80,7 +80,7 @@ When we spoke about *pure functions*, we said they take 1 input to 1 output. Cur No matter if the output is another function - it qualifies as pure. We do allow more than one argument at a time, but this is seen as merely removing the extra `()`'s for convenience. -## In summary +## In Summary Currying is handy and I very much enjoy working with curried functions on a daily basis. It is a tool for the belt that makes functional programming less verbose and tedious. @@ -92,7 +92,7 @@ Let's acquire another essential tool called `compose`. ## Exercises -#### Note About Exercises +#### Note about Exercises Throughout the book, you might encounter an 'Exercises' section like this one. Exercises can be done directly in-browser provided you're reading from [gitbook](https://mostly-adequate.gitbooks.io/mostly-adequate-guide) (recommended). @@ -105,7 +105,7 @@ they present; as a matter of fact, consider them available as well. > Hint: you can submit your solution by doing `Ctrl + Enter` in the embedded editor! -#### Running Exercises On Your Machine (Optional) +#### Running Exercises on Your Machine (optional) Should you prefer to do exercises directly in files using your own editor: @@ -118,7 +118,7 @@ Should you prefer to do exercises directly in files using your own editor: Unit tests will run against your answers and provide hints in case of mistake. By the by, the answers to the exercises are available in files named *answers\_\**. -#### Let's practice! +#### Let's Practice! {% exercise %} Refactor to remove all arguments by partially applying the function. diff --git a/ch05.md b/ch05.md index 6d78f264..faf03803 100644 --- a/ch05.md +++ b/ch05.md @@ -1,6 +1,6 @@ # Chapter 05: Coding by Composing -## Functional husbandry +## Functional Husbandry Here's `compose`: @@ -187,7 +187,7 @@ The `trace` function allows us to view the data at a certain point for debugging Composition will be our tool for constructing programs and, as luck would have it, is backed by a powerful theory that ensures things will work out for us. Let's examine this theory. -## Category theory +## Category Theory Category theory is an abstract branch of mathematics that can formalize concepts from several different branches such as set theory, type theory, group theory, logic, and more. It primarily deals with objects, morphisms, and transformations, which mirrors programming quite closely. Here is a chart of the same concepts as viewed from each separate theory. diff --git a/ch06.md b/ch06.md index 5a30718e..0ce08d01 100644 --- a/ch06.md +++ b/ch06.md @@ -1,6 +1,6 @@ # Chapter 06: Example Application -## Declarative coding +## Declarative Coding We are going to switch our mindset. From here on out, we'll stop telling the computer how to do its job and instead write a specification of what we'd like as a result. I'm sure you'll find it much less stressful than trying to micromanage everything all the time. @@ -46,7 +46,7 @@ Though there's nothing necessarily wrong with the imperative version, there is s Because we are not encoding order of evaluation, declarative coding lends itself to parallel computing. This coupled with pure functions is why FP is a good option for the parallel future - we don't really need to do anything special to achieve parallel/concurrent systems. -## A flickr of functional programming +## A Flickr of Functional Programming We will now build an example application in a declarative, composable way. We'll still cheat and use side effects for now, but we'll keep them minimal and separate from our pure codebase. We are going to build a browser widget that sucks in flickr images and displays them. Let's start by scaffolding the app. Here's the html: diff --git a/ch07.md b/ch07.md index bfc86c18..d8d1b434 100644 --- a/ch07.md +++ b/ch07.md @@ -1,6 +1,6 @@ -# Chapter 07: Hindley-Milner and Me +# Chapter 07: Hindley-milner and Me -## What's your type? +## What's Your Type? If you're new to the functional world, it won't be long before you find yourself knee deep in type signatures. Types are the meta language that enables people from all different backgrounds to communicate succinctly and effectively. For the most part, they're written with a system called "Hindley-Milner", which we'll be examining together in this chapter. When working with pure functions, type signatures have an expressive power to which the English language cannot hold a candle. These signatures whisper in your ear the intimate secrets of a function. In a single, compact line, they expose behaviour and intention. We can derive "free theorems" from them. Types can be inferred so there's no need for explicit type annotations. They can be tuned to fine point precision or left general and abstract. They are not only useful for compile time checks, but also turn out to be the best possible documentation available. Type signatures thus play an important part in functional programming - much more than you might first expect. @@ -10,7 +10,7 @@ JavaScript is a dynamic language, but that does not mean we avoid types all toge There are type checking tools available for JavaScript such as [Flow](http://flowtype.org/) or the typed dialect, [TypeScript](http://www.typescriptlang.org/). The aim of this book is to equip one with the tools to write functional code so we'll stick with the standard type system used across FP languages. -## Tales from the cryptic +## Tales from the Cryptic From the dusty pages of math books, across the vast sea of white papers, amongst casual Saturday morning blog posts, down into the source code itself, we find Hindley-Milner type signatures. The system is quite simple, but warrants a quick explanation and some practice to fully absorb the little language. @@ -106,7 +106,7 @@ const reduce = curry((f, x, xs) => xs.reduce(f, x)); Ahem, here goes nothing....looking at the signature, we see the first argument is a function that expects a `b`, an `a`, and produces a `b`. Where might it get these `a`s and `b`s? Well, the following arguments in the signature are a `b` and an array of `a`s so we can only assume that the `b` and each of those `a`s will be fed in. We also see that the result of the function is a `b` so the thinking here is our final incantation of the passed in function will be our output value. Knowing what reduce does, we can state that the above investigation is accurate. -## Narrowing the possibility +## Narrowing the Possibility Once a type variable is introduced, there emerges a curious property called *[parametricity](https://en.wikipedia.org/wiki/Parametricity)*. This property states that a function will *act on all types in a uniform manner*. Let's investigate: @@ -126,7 +126,7 @@ From the type signature alone, what could `reverse` possibly be up to? Again, it This narrowing of possibility allows us to use type signature search engines like [Hoogle](https://www.haskell.org/hoogle) to find a function we're after. The information packed tightly into a signature is quite powerful indeed. -## Free as in theorem +## Free as in Theorem Besides deducing implementation possibilities, this sort of reasoning gains us *free theorems*. What follows are a few random example theorems lifted directly from [Wadler's paper on the subject](http://ttic.uchicago.edu/~dreyer/course/papers/wadler.pdf). diff --git a/ch08.md b/ch08.md index 5a23a6ba..8d895bff 100644 --- a/ch08.md +++ b/ch08.md @@ -140,7 +140,7 @@ const map = curry((f, anyFunctor) => anyFunctor.map(f)); This is delightful as we can carry on with composition per usual and `map` will work as expected. This is the case with ramda's `map` as well. We'll use dot notation when it's instructive and the pointfree version when it's convenient. Did you notice that? I've sneakily introduced extra notation into our type signature. The `Functor f =>` tells us that `f` must be a Functor. Not that difficult, but I felt I should mention it. -## Use cases +## Use Cases In the wild, we'll typically see `Maybe` used in functions which might fail to return a result. @@ -191,7 +191,7 @@ getTwenty({ balance: 10.00 }); `withdraw` will tip its nose at us and return `Nothing` if we're short on cash. This function also communicates its fickleness and leaves us no choice, but to `map` everything afterwards. The difference is that the `null` was intentional here. Instead of a `Just('..')`, we get the `Nothing` back to signal failure and our application effectively halts in its tracks. This is important to note: if the `withdraw` fails, then `map` will sever the rest of our computation since it doesn't ever run the mapped functions, namely `finishTransaction`. This is precisely the intended behaviour as we'd prefer not to update our ledger or show a new balance if we hadn't successfully withdrawn funds. -## Releasing the value +## Releasing the Value One thing people often miss is that there will always be an end of the line; some effecting function that sends JSON along, or prints to the screen, or alters our filesystem, or what have you. We cannot deliver the output with `return`, we must run some function or another to send it out into the world. We can phrase it like a Zen Buddhist koan: "If a program has no observable effect, does it even run?". Does it run correctly for its own satisfaction? I suspect it merely burns some cycles and goes back to sleep... @@ -371,7 +371,7 @@ zoltar({ birthDate: 'balloons!' }); Finally, a use for that mysterious `id` function. It simply parrots back the value in the `Left` to pass the error message to `console.log`. We've made our fortune telling app more robust by enforcing error handling from within `getAge`. We either slap the user with a hard truth like a high five from a palm reader or we carry on with our process. And with that, we're ready to move on to an entirely different type of functor. -## Old McDonald had Effects... +## Old McDonald Had Effects... dominoes.. need a reference diff --git a/ch09.md b/ch09.md index 7b2eda1e..9895a2e0 100644 --- a/ch09.md +++ b/ch09.md @@ -188,7 +188,7 @@ applyPreferences('preferences').unsafePerformIO(); `getItem` returns an `IO String` so we `map` to parse it. Both `log` and `setStyle` return `IO`'s themselves so we must `join` to keep our nesting under control. -## My chain hits my chest +## My Chain Hits My Chest chain @@ -285,7 +285,7 @@ Don't worry if these examples are hard to grasp at first. Play with them. Poke t As a reminder, this does not work with two different nested types. Functor composition and later, monad transformers, can help us in that situation. -## Power trip +## Power Trip Container style programming can be confusing at times. We sometimes find ourselves struggling to understand how many containers deep a value is or if we need `map` or `chain` (soon we'll see more container methods). We can greatly improve debugging with tricks like implementing `inspect` and we'll learn how to create a "stack" that can handle whatever effects we throw at it, but there are times when we question if it's worth the hassle. diff --git a/ch10.md b/ch10.md index fbb141c1..0841d718 100644 --- a/ch10.md +++ b/ch10.md @@ -33,7 +33,7 @@ The issue here is that we are stuck in the sequential world of monads wherein no In fact, it would be lovely if we could succinctly apply one functor's contents to another's value without these needless functions and variables should we find ourselves in this pickle jar. -## Ships in bottles +## Ships in Bottles http://hollycarden.deviantart.com @@ -121,7 +121,7 @@ IO.of(signIn).ap(getVal('#email')).ap(getVal('#password')).ap(IO.of(false)); `signIn` is a curried function of 3 arguments so we have to `ap` accordingly. With each `ap`, `signIn` receives one more argument until it is complete and runs. We can continue this pattern with as many arguments as necessary. Another thing to note is that two arguments end up naturally in `IO` whereas the last one needs a little help from `of` to lift it into `IO` since `ap` expects the function and all its arguments to be in the same type. -## Bro, do you even lift? +## Bro, Do You Even Lift? Let's examine a pointfree way to write these applicative calls. Since we know `map` is equal to `of/ap`, we can write generic functions that will `ap` as many times as we specify: @@ -191,7 +191,7 @@ map(add, Right(2)).ap(Right(3)); It's helpful to know that `<$>` is `map` (aka `fmap`) and `<*>` is just `ap`. This allows for a more natural function application style and can help remove some parenthesis. -## Free can openers +## Free Can Openers http://breannabeckmeyer.com/drawing.html We haven't spoken much about derived functions. Seeing as all of these interfaces are built off of each other and obey a set of laws, we can define some weaker interfaces in terms of the stronger ones. diff --git a/ch12.md b/ch12.md index 417d46f0..da3e430e 100644 --- a/ch12.md +++ b/ch12.md @@ -131,7 +131,7 @@ const getControlNode = compose(chain(traverse(IO.of, $)), map(getAttribute('aria Instead of `map(map($))` we have `chain(traverse(IO.of, $))` which inverts our types as it maps then flattens the two `IO`s via `chain`. -## No Law And Order +## No Law and Order Well now, before you get all judgemental and bang the backspace button like a gavel to retreat from the chapter, take a moment to recognize that these laws are useful code guarantees. Tis' my conjecture that the goal of most program architecture is an attempt to place useful restrictions on our code to narrow the possibilities, to guide us into the answers as designers and readers.