Mostly adequate guide to FP (in javascript)

Overview

cover

About this book

This is a book on the functional paradigm in general. We'll use the world's most popular functional programming language: JavaScript. Some may feel this is a poor choice as it's against the grain of the current culture which, at the moment, feels predominately imperative. However, I believe it is the best way to learn FP for several reasons:

  • You likely use it every day at work.

    This makes it possible to practice and apply your acquired knowledge each day on real world programs rather than pet projects on nights and weekends in an esoteric FP language.

  • We don't have to learn everything up front to start writing programs.

    In a pure functional language, you cannot log a variable or read a DOM node without using monads. Here we can cheat a little as we learn to purify our codebase. It's also easier to get started in this language since it's mixed paradigm and you can fall back on your current practices while there are gaps in your knowledge.

  • The language is fully capable of writing top notch functional code.

    We have all the features we need to mimic a language like Scala or Haskell with the help of a tiny library or two. Object-oriented programming currently dominates the industry, but it's clearly awkward in JavaScript. It's akin to camping off of a highway or tap dancing in galoshes. We have to bind all over the place lest this change out from under us, we have various work arounds for the quirky behavior when the new keyword is forgotten, private members are only available via closures. To a lot of us, FP feels more natural anyways.

That said, typed functional languages will, without a doubt, be the best place to code in the style presented by this book. JavaScript will be our means of learning a paradigm, where you apply it is up to you. Luckily, the interfaces are mathematical and, as such, ubiquitous. You'll find yourself at home with Swiftz, Scalaz, Haskell, PureScript, and other mathematically inclined environments.

Read it Online

For a best reading experience, read it online via Gitbook.

  • Quick-access side-bar
  • In-browser exercises
  • In-depth examples

Play Around with Code

To make the training efficient and not get too bored while I am telling you another story, make sure to play around with the concepts introduced in this book. Some can be tricky to catch at first and are better understood by getting your hands dirty. All functions and algebraic data-structures presented in the book are gathered in the appendixes. The corresponding code is also available as an npm module:

$ npm i @mostly-adequate/support

Alternatively, exercises of each chapter are runnable and can be completed in your editor! For example, complete the exercise_*.js in exercises/ch04 and then run:

$ npm run ch04

Download it

Do it yourself

git clone https://github.com/MostlyAdequate/mostly-adequate-guide.git
cd mostly-adequate-guide/
npm install
npm run setup
npm run generate-pdf
npm run generate-epub

Note! To generate the ebook version you will need to install ebook-convert. Installation instructions.

Table of Contents

See SUMMARY.md

Contributing

See CONTRIBUTING.md

Translations

See TRANSLATIONS.md

FAQ

See FAQ.md

Plans for the future

  • Part 1 (chapters 1-7) is a guide to the basics. I'm updating as I find errors since this is the initial draft. Feel free to help!
  • Part 2 (chapters 8-13) address type classes like functors and monads all the way through to traversable. I hope to squeeze in transformers and a pure application.
  • Part 3 (chapters 14+) will start to dance the fine line between practical programming and academic absurdity. We'll look at comonads, f-algebras, free monads, yoneda, and other categorical constructs.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

Comments
  • Update to ES6 | ES2015 (revived)

    Update to ES6 | ES2015 (revived)

    I've accidentally deleted my previous repository #235

    From old PR

    • [x] Chapter 1
    • [x] Chapter 2
    • [x] Chapter 3
    • [x] Chapter 4
    • [x] Chapter 5
    • [x] Chapter 6
    • [x] Chapter 7
    • [ ] Chapter 8 (updated but needs feedback)
    • [ ] Chapter 9 (updated but needs feedback)
    • [ ] Chapter 10 (updated but needs feedback)
    • [x] Write tests for all examples or make all examples runnable?
    • [ ] Update FAQ
    • [ ] Update images (app example)
    • [ ] What to do with fn declared by const with the same name? index e.g. f1, f1 them or use let instead

    Links that need to point to the correct location in Master. Might be easier to fix after merge.

    • [ ] Update paths to exercises
    • [ ] grep for part1_
    • [ ] grep for part2_

    I think we should update the text and provide a better OOP example. The code is still very verbose. We could also keep the current mutating code and just call it imperative instead of OOP.

    class Flock {
      constructor(n) {
        this.seagulls = n;
      }
    
      conjoin({seagulls}) {
        return new Flock(this.seagulls + seagulls);
      }
    
      breed({seagulls}) {
        return new Flock(this.seagulls * seagulls);
      }
    }
    

    Based on: https://gist.github.com/eshacker/be153d852b9b995f42dd

    opened by christiantakle 75
  • Plans for part 3

    Plans for part 3

    First, the book is awesome. So awesome I am wondering, are there are plans for part 3? :).

    Or Else, if there are good resources someone can point about the topics on part 3 (comonads, f-algebras, free monads, yoneda).

    DISCUSSION 
    opened by Fabs 36
  • Update to ES6 | ES2015

    Update to ES6 | ES2015

    • [x] Chapter 1
    • [x] Chapter 2
    • [x] Chapter 3
    • [x] Chapter 4
    • [ ] Chapter 5
    • [ ] Chapter 6
    • [ ] Chapter 7
    • [ ] Chapter 8
    • [ ] Chapter 9
    • [ ] Chapter 10
    • [ ] Write tests for all examples or make all examples runnable?

    I think we should update the text and provide a better OOP example. The code is still very verbose. We could also keep the current mutating code and just call it imperative instead of OOP.

    class Flock {
      constructor(n) {
        this.seagulls = n;
      }
    
      conjoin(other) {
        return new Flock2(this.seagulls + other.seagulls);
      }
    
      breed(other) {
        return new Flock2(this.seagulls * other.seagulls);
      }
    }
    

    Based on: https://gist.github.com/eshacker/be153d852b9b995f42dd

    opened by christiantakle 20
  • Chapter 3 pure function is impure

    Chapter 3 pure function is impure

    In chapter 3, there is given an example under the point reasonable. The description make the assertion that the functions decrementHP, isSameTeamand punchare all pure.

    In my point of view, this is not correct for the punchfunction. In fact, this function consumes isSameTeam and decrementHP over its context (scope). Therefor, this function has this hidden dependencies and can not be asserted as pure:

    var punch = function(player, target) {
      return isSameTeam(player, target) ? target : decrementHP(target);
    };
    

    To become pure, both functions should be declared as function arguments for punch.

    var punch = function(isSameTeam, decrementHP, player, target) {
      return isSameTeam(player, target) ? target : decrementHP(target);
    };
    

    What do you think? If you agree, i'd be happy to can make the PR 😄

    Best, André

    DISCUSSION 
    opened by awaltert 19
  • Lack of real world examples

    Lack of real world examples

    I've done reading all available chapters in this book and I think that this is the best available guide about FP ever. But the problem is that like others it miss real world examples. I'm requesting to add chapter with an implementation of some non trivial application, that uses all the staff explained in this books. I suggest to use more complex example than flickr.

    opened by gyzerok 18
  • Request add translation to Indonesia

    Request add translation to Indonesia

    Hello, I am very interested to read this project. May I translate this project into Indonesian? I am also an Indonesian translator. If allowed I will be happy to start translating this project. :)

    Thank you.

    opened by anaufalm 15
  • Restructuring

    Restructuring

    Change the shape of the original project to reduce duplication and make it easier to refine.

    TODO

    • [x] Check support url in FAQ.md
    • [x] grep for part1_
    • [x] grep for part2_

    Consider fixing: #264

    Note

    Markers do not work in the current version of 'include-codeblock' https://github.com/azu/gitbook-plugin-include-codeblock/issues/33

    opened by christiantakle 11
  • Correction for ex4 in chapter 8

    Correction for ex4 in chapter 8

    I think there is just a small problem. These two checks are not equivalent:

    // example function check
    if (n) // false for: null, undefined, 0, NaN, ""
    
    // Maybe check
    (this.__value === null || this.__value === undefined) ?
    

    my suggested correction:

    var ex4 = function(n) {
      if (n !== null && n !== undefined) {
        return parseInt(n);
      }
    };
    

    References:

    // Exercise 4
    // ==========
    // Use Maybe to rewrite ex4 without an if statement
    
    var ex4 = function (n) {
      if (n) { return parseInt(n); }
    };
    
    var ex4 = _.compose(_.map(parseInt), Maybe.of);
    
    var Maybe = function(x) {
      this.__value = x;
    };
    
    Maybe.of = function(x) {
      return new Maybe(x);
    };
    
    Maybe.prototype.isNothing = function() {
      return (this.__value === null || this.__value === undefined);
    };
    
    Maybe.prototype.map = function(f) {
      return this.isNothing() ? Maybe.of(null) : Maybe.of(f(this.__value));
    };
    
    FIXED 
    opened by thurt 11
  • Links to gitbooks broken

    Links to gitbooks broken

    The links to gitbooks all go to https://www.gitbook.com/?utm_source=legacy&utm_medium=redirect&utm_campaign=close_legacy.

    This is probably because the transition to from the legacy site to their new site.

    Did you run through the Migrating your content process?

    opened by frazjp65 10
  • How does the reduce call work in the reverse() example?

    How does the reduce call work in the reverse() example?

    I can't find an implementation of reduce() that this line of code works with from your example:

    var reverse = reduce(function(acc, x){ return [x].concat(acc); }, []);

    Is it a typo or can you provide a link that would explain how this reverse function operates?

    And, to demonstrate my further confusion, shouldn't reverse be in the form of a composable pure function with one argument, as in reverse=function(x) {..} in order to be used with compose?

    opened by tsummerall 10
  • Curry Exercise 2: filterQs does not, in fact, filter Q's

    Curry Exercise 2: filterQs does not, in fact, filter Q's

    When the filterQs function from Curry Exercise 2 is applied to test array (['quick', 'camels', 'quarry', 'over', 'quails']) it returns the same array unchanged.

    The cause of this is the match function which is used by filterQs. It returns empty array when the regexp and string to which it is being applied does not match each other. Empty array is considered truthy, so the Ramda's filter does not filter anything.

    I made provided test pass by changing the function to this: var filterQs = _.reject(_.compose(_.isEmpty, _.match(/q/i)));

    But this is probably not the best way to solve the exercise, as composition is subject of the next chapter.

    As possible solution, the Ramda's match can be replaced with the match from the support module, so the exercise will look like this:

    // Exercise 2
    //==============
    // Refactor to remove all arguments by partially applying the functions
    // Use the provided _match function
    
    // LEAVE BE:
    var _match = _.curry(function(what, x) { return x.match(what); });
    
    // REFACTOR THIS ONE:
    var filterQs = function(xs) {
      return _.filter(function(x){ return _match(/q/i, x);  }, xs);
    };
    
    opened by endrin 10
  • ch12: The result of `comp1` is not proper

    ch12: The result of `comp1` is not proper

    original content

    const comp1 = compose(sequence(Compose.of), map(Compose.of));
    const comp2 = (Fof, Gof) => compose(Compose.of, map(sequence(Gof)), sequence(Fof));
    
    
    // Test it out with some types we have lying around
    comp1(Identity(Right([true])));
    // Compose(Right([Identity(true)]))
    
    comp2(Either.of, Array)(Identity(Right([true])));
    // Compose(Right([Identity(true)]))
    

    issue

    I disagree with the result of comp1(Identity(Right([true]))) will be Compose(Right([Identity(true)])). As it's mentioned in the Identity law:

    const identity1 = compose(sequence(Identity.of), map(Identity.of));
    const identity2 = Identity.of;
    
    // test it out with Right
    identity1(Either.of('stuff'));
    // Identity(Right('stuff'))
    
    identity2(Either.of('stuff'));
    // Identity(Right('stuff'))
    

    identity1 is equivalent to identity2. And I think comp1 is isomorphic to identity1, which means comp1 is equivalent to Compose.of. So the result of comp1(Identity(Right([true]))) should be Compose(Identity(Right([true]))).

    maybe a solution

    I'm not sure whether sequence will exchange the containers that are not adjacent, like this:

    sequence(A.of, C(B(A(x))));
    // A(B(C(x)))
    

    If the law is right, I think the proper comp1 should equal compose(sequence(Compose.of), map(map(map(Compose.of))))

    opened by dzylikecode 0
  • broken gitbook navigation

    broken gitbook navigation

    As in title, git book navigation is broken. When you click in left menu on any subchapter, only thing visible is white sheet.Only way to see subchapters is to click on chapter and then scroll down. Also navigation button on the bottom of page is wrong because "next" button says name of first subchapter of given chapter.

    opened by pociej 1
  • Has this been ported over to other programming languages?

    Has this been ported over to other programming languages?

    I'm assuming, according to the license and copyright, this book can be ported / translated for other programming languages, as long as there's attribution to the original author (and obviously they can't make any money from it)

    Has anyone done it?

    opened by ArtGangsta 2
  • Hey, great stuff :)

    Hey, great stuff :)

    Hey, great stuff :) And I pretty much agree with everything you mentioned on #479. Are you interested in fixing those few other points as well? (Including #191 ?)

    Incidentally, this will require to define this append in the appendix :+1:

    Originally posted by @KtorZ in https://github.com/MostlyAdequate/mostly-adequate-guide/issues/482#issuecomment-429650964

    opened by noofh-22 0
  • Timeline for Part 3 (chapters 14+)

    Timeline for Part 3 (chapters 14+)

    Is there a timeline for Part 3? This book is amazing and should be completed if there was some justice in the world. The author mentions "academic absurdity" in connection to this part. I covered a bit of it in my math degree project, which can be consulted here: https://salvalcantara.gumroad.com/l/soGyY. If you use "lambda" or "gamma" discount codes, you should be able to download it for free (al least, the first ones who try). Maybe it could serve as a guide or maybe you had something entirely different in mind. In any case, please finish the book!

    opened by salvalcantara 0
Owner
null
A simple To-do list page, build with Webpack, HTML, CSS, and mostly JavaScript

This is a simple To-do list page, build with Webpack, HTML, CSS, and mostly JavaScript. You can add, remove, edit and complete tasks, then clear all completed.

Joaquín G. L. Z. 4 Mar 4, 2022
A collection of (mostly) technical things every software developer should know about

Join our community for professional Software Developers and get more control over your life and career! Every Programmer Should Know ?? A collection o

MTDV 66.6k Jan 4, 2023
This is a (pretty broken, but mostly functional) organic-shaped jigsaw generator with custom border support

OrganicPuzzleJs This is a (pretty broken, but mostly functional) organic-shaped jigsaw generator with custom border support. It relies on two linbrari

null 6 Dec 10, 2022
List of awesome people offering their time for free to have a "coffee chat" with others about different topics, mostly in a mentorship kind of way.

Coffee Chat List of awesome people offering their time for free to have a "coffee chat" with others about different topics, mostly in a mentorship kin

Frédéric Harper 91 Dec 12, 2022
A (mostly) blank Ultra project

A (mostly) blank Ultra project

Exhibitionist 31 Aug 12, 2022
A pleasing darker theme made mostly with complementary purple and blue colors, occasionally with a touch of pink or red.

Nebula Float away in space with a beautiful blurple oriented color theme. DISCLAIMER: ⚠️ This theme is not as high contrast as other themes. A pleasin

catgirlkelly 5 Nov 23, 2022
JavaScript Style Guide

Airbnb JavaScript Style Guide() { A mostly reasonable approach to JavaScript Note: this guide assumes you are using Babel, and requires that you use b

Airbnb 130.5k Jan 4, 2023
A learning guide for JavaScript programmers.

Table of Contents Awesome JavaScript 专题列表 基础 开发准备 推荐的书 源代码阅读 敏捷方法与工具 JavaScript ES6 Node.js 图书 最佳实践 风格指南 常用的Node Web框架 常用NPM工具模块 开发工具和库 Future Awesome

Sun 785 Dec 26, 2022
AirBnb Javascript Style Guide'ının Türkçe diline çevrildiği repository

Airbnb JavaScript Stil Kılavuzu() { JavaScript'e büyük ölçüde mantıklı/makul bir yaklaşım Not: Bu kılavuz sizin Babel kullandığınızı varsayar ve babel

Gökhan Kandemir 71 Dec 29, 2022
A Complete Javascript Learning Reference Guide.

Learn Javascript A Javascript Reference Repository, which was initially created for my refernce is now open. Any one can Learn and Add more Content to

Abdul Rehman Kalsekar 18 Oct 26, 2022
📚 Study guide and introduction to the modern front end stack.

Grab Front End Guide Credits: Illustration by @yangheng This guide has been cross-posted on Free Code Camp. Grab is Southeast Asia (SEA)'s leading tra

Grab 14.7k Jan 3, 2023
:books: The definitive guide to TypeScript and possibly the best TypeScript book :book:. Free and Open Source 🌹

TypeScript Deep Dive I've been looking at the issues that turn up commonly when people start using TypeScript. This is based on the lessons from Stack

Basarat Ali Syed 18.7k Jan 4, 2023
Frontend tech guide and collection of highly recommended materials

Frontend Learning Kit Frontend tech guide and collection of highly recommended materials Show your support by giving a ⭐ to this repo 2022 Frontend De

Sadanand Akshay Pai 2.9k Jan 7, 2023
Dev Guide for Archival Node & Indexer Setup

Algorand - The Undocumented Docs Dev Notes for Archival Node, Indexer Setup (and more) Archival Node FAQ [ ? ] How much space will I need? See -> http

null 5 May 23, 2022
A simple guide to HTML elements

?? HEAD A simple guide to HTML <head> elements Table of Contents Recommended Minimum Elements Meta Link Icons Social Facebook Open Graph Twitter Card

Josh Buchea 29.5k Jan 1, 2023
A kickstarter guide to writing ES6

ES6 for Humans ?? The complete guide is now available on Amazon Table of Contents let, const and block scoping Arrow Functions Default Function Parame

Deepak Grover 6.3k Jan 4, 2023
A website that acts as a guide about the universities to potential students whole throughout the globe.

A website that acts as a guide about the universities to potential students whole throughout the globe.

null 1 Apr 15, 2022
Vercel's engineering style guide

The Vercel Style Guide This repository is the home of Vercel's style guide, which includes configs for popular linting and styling tools. The followin

Vercel 409 Jan 6, 2023
Solidity Quickstart is an extensive solidity guide for the solidity newbies out there.

?? Solidity Quickstart Solidity Quickstart is an extensive solidity guide for the solidity newbies out there. ?? How does it work? All the guides rela

Kira 8 Aug 6, 2022