{"componentChunkName":"component---node-modules-gatsby-theme-chronoblog-src-templates-post-js","path":"/intro-to-functional-programming/","result":{"data":{"mdx":{"id":"fb25a3b1-75ac-554f-abcd-cfe246ba00c8","excerpt":"What is Functional Programming? Wikipedia: In computer science, functional programming is a programming paradigm- a style of building the…","frontmatter":{"title":"Yet another introduction to functional programming","date":"2019-12-02T00:00:00.000Z","description":null,"tags":["post","fp","javascript"],"cover":null},"fields":{"slug":"/intro-to-functional-programming/"},"body":"function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"title\": \"Yet another introduction to functional programming\",\n  \"date\": \"2019-12-02T00:00:00.000Z\",\n  \"tags\": [\"post\", \"fp\", \"javascript\"]\n};\n\nvar makeShortcode = function makeShortcode(name) {\n  return function MDXDefaultShortcode(props) {\n    console.warn(\"Component \" + name + \" was not imported, exported, or provided by MDXProvider as global scope\");\n    return mdx(\"div\", props);\n  };\n};\n\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"h3\", {\n    \"id\": \"what-is-functional-programming\"\n  }, \"What is Functional Programming?\"), mdx(\"p\", null, \"Wikipedia:\"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"In computer science, functional programming is a programming paradigm- a style of building the structure and elements of computer programs-that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data.\")), mdx(\"p\", null, \"I love Wikipedia as much as the next person, but that definition doesn\\u2019t give a great first impression. Let\\u2019s break each piece of this definition down into small chunks, and by the end of this post we\\u2019ll be able to compose them back together to reach an understanding.\"), mdx(\"p\", null, \"Functional programming or FP for short, is a programming paradigm \\u2014 meaning it is a style of programming. Consider some other programming paradigms you\\u2019re likely familiar with: (procedural, object oriented, etc.). These are just rule sets we use to structure the way we as developers write code and think about the problems we\\u2019re solving.\"), mdx(\"p\", null, \"Many languages have been built to enforce some of the important \\u201Claws\\u201D of functional programming and are designed entirely around the paradigm. These languages are very fun to use and I\\u2019d highly encourage you to try a few of them out. That being said, the purpose of this post is not to learn a functional language. We\\u2019re going to learn what functional programming is, and how you can use its concepts inside the code you write everyday.\"), mdx(\"h3\", {\n    \"id\": \"what-is-our-goal-with-functional-programming\"\n  }, \"What is our goal with functional programming?\"), mdx(\"p\", null, \"We\\u2019ve established that functional programming is a style of writing programs and representing computations. Before going any further though, I think it\\u2019s important to outline an overall goal that this style of programming is trying to achieve. It\\u2019s hard to get excited about a new tool if you don\\u2019t know what its used for. That being said, we have one and only one goal with FP: make programs simpler.\"), mdx(\"p\", null, \"Now, although that idea took three words to explain and sounds pretty trivial allow me to assure you that making programs simpler is NOT an easy task. In fact, you could argue that people have been working on this problem since computers have existed. Every programming language that has been written likely began with the goal of making our lives as programmers easier. The reason you and I don\\u2019t have to specify register addresses when we write a bubble sort is a clear benchmark that shows us programming has gotten simpler as time has progressed. Our brains can now think less about the computer\\u2019s inner-workings and spend more time thinking about our program\\u2019s process. Much progress has been made in the years before us, but we can still do better. Functional programming provides us with some rules for our code that can provide more simplicity in our programs. These rules can be broken up into three focus points:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Abstracting out common processes\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Avoiding mutating state / Isolating state mutation\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Writing declarative and composable code\")), mdx(\"p\", null, \"If some of these words or phrases don\\u2019t make sense right now that is totally fine. I want to cover each of these in good detail and provide some code examples along the way. Before doing a detailed deep-dive let\\u2019s start with a question: how do we \\u201Cdo\\u201D functional programming?\"), mdx(\"p\", null, \"One of the more obvious ways you might think to \\u201Cdo\\u201D functional programming is to express our program in terms of functions. And that\\u2019s actually a great place to start! Writing our programs as a composition of smaller bite-sized functions is a key part of FP. To get a better idea of what that means let\\u2019s transform some non-functional code into functional code.\"), mdx(\"p\", null, \"Non-Functional:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const greeting = \\\"Hi, I'm \\\"\\nconst name_1 = \\\"Jay\\\"\\nconst name_2 = \\\"Eric\\\"\\nconst name_3 = \\\"Pranshu\\\"\\n\\nconsole.log(greeting + ' ' + name_1) // \\\"Hi, I'm Jay\\\"\\nconsole.log(greeting + ' ' + name_2) // \\\"Hi, I'm Eric\\\"\\nconsole.log(greeting + ' ' + name_3) // \\\"Hi, I'm Pranshu\\\"\\n\")), mdx(\"p\", null, \"Functional:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const name_1 = \\\"Jay\\\"\\nconst name_2 = \\\"Eric\\\"\\nconst name_3 = \\\"Pranshu\\\"\\n\\nfunction greet(name) {\\n    return \\\"Hi, I'm \\\" + name\\n}\\n\\nconsole.log(greet(name_1)) // \\\"Hi, I'm Jay\\\"\\nconsole.log(greet(name_2)) // \\\"Hi, I'm Eric\\\"\\nconsole.log(greet(name_3)) // \\\"Hi, I'm Pranshu\\\"\\n\")), mdx(\"p\", null, \"Nothing too ground-breaking here. We\\u2019ve abstracted out a common process in our program into a function which we can reuse. In short, our program has has been expressed in terms of functions instead of statements. Let\\u2019s look at a more complex snippet of code and try to apply this same style of thinking.\"), mdx(\"p\", null, \"Non-Functional:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"function willCarRun(car, driver) {\\n    let assembled;\\n    \\n    if(car.isTotaled) {\\n        if(driver.isMechanic) {\\n            assembled = true;\\n        }\\n        else {\\n            assembled = false;\\n        }\\n    }\\n    else {\\n        assembled = true;\\n    }\\n    \\n    return assembled && car.hasGas;\\n}\\n\")), mdx(\"p\", null, \"Functional:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"function isAssembled(car, driver) {\\n    return !car.isTotalled || driver.isMechanic\\n}\\n\\nfunction willCarRun(car, driver) {\\n    return isAssembled(car, driver) && car.hasGas\\n}\\n\")), mdx(\"p\", null, \"One of our focus areas of FP is avoiding mutation. We\\u2019ll go into more detail on the benefits of immutability later, but a good rule of thumb for making our programs more functional is to avoid reassignment. In the functional version of the code, we have the exact same logic as before, but we\\u2019ve extracted it out to a separate function making it much easier to reason about.\"), mdx(\"p\", null, \"Now that we\\u2019ve seen an overview of what functional code looks like, we can get more into the nitty-gritty details. We\\u2019ll dive into other techniques for writing functional programs, and more importantly I\\u2019ll walk through the benefits of writing our code this way.\"), mdx(\"hr\", null), mdx(\"h3\", {\n    \"id\": \"immutability--pure-functions\"\n  }, \"Immutability & Pure Functions\"), mdx(\"p\", null, mdx(\"em\", {\n    parentName: \"p\"\n  }, \"Before we begin, I\\u2019d like to take a second and apologize on behalf of the entire functional programming community. We are going to be seeing a lot of terminology in the next few sections of this post. Bare with me. It\\u2019s not difficult to understand, but it sounds intimidating at first. With that being said I\\u2019ll do my best to explain all the terms I use!\")), mdx(\"p\", null, \"A core piece of the functional programming pie is avoiding state mutation as much as possible. State mutation can be anything from changing a variable\\u2019s value, writing to a file, or updating an array entry. Although it may not be obvious, avoiding data mutation in our code is a great way to simplify programs. When state change is minimized, designing, debugging, and reasoning about our programs becomes much easier. Now, unfortunately we can\\u2019t totally eliminate state mutation. Without state changing, our programs would be useless! Even the most basic \\u201CHello, World!\\u201D program writes to a stdout file. That being said, we can work on minimizing and isolating state mutation in our code to help simplify things.\"), mdx(\"p\", null, \"One way we can put this idea of immutability into action is by defining our programs as a composition of these things called, \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"pure functions\"), \".\"), mdx(\"p\", null, \"A \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"pure function\"), \" is just a regular ol\\u2019 function that satisfies a few properties:\"), mdx(\"p\", null, \"1.) It is a deterministic function (the same input ALWAYS gives the same output).\"), mdx(\"p\", null, \"2.) The output of the function solely depends on the function\\u2019s input (no reading of state outside the function)\"), mdx(\"p\", null, \"3.) No \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"side-effects\"), \" take place inside the function.\"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"A \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"side-effect\"), \" is anything a function does that affects the \\u201Cworld\\u201D outside of the function. This can be anything from writing to a file or mutating a global variable. A good way to think about it: if there is some way to tell that a function was invoked inside your program, that function contains side-effects.\")), mdx(\"p\", null, \"Impure function:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"let count = 0;\\n\\nfunction incrementCountBy(x){\\n    // side effect because we are mutating state outside the function\\n    count += x\\n    \\n    // writing to IO stream is a side effect\\n    console.log('Incremeneted by: ', x)\\n    \\n    // return value is non-deterministic, and isn't dependent on our input\\n    return Math.random()\\n}\\n\")), mdx(\"p\", null, \"Pure function:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"function incrementBy(count, x) {\\n    return count + x\\n}\\n\")), mdx(\"h4\", {\n    \"id\": \"how-do-pure-functions-and-immutability-benefit-us\"\n  }, \"How do pure functions and immutability benefit us?\"), mdx(\"p\", null, \"When we write a pure function we\\u2019re giving ourselves a free guarantee that no state will change during the call of that function. The ONLY thing we have to be concerned with is the function\\u2019s input and output. This means we don\\u2019t have to think about the \\u201Cworld\\u201D outside the function. We don\\u2019t need to think about what values are mutated where and by what in our program.\"), mdx(\"p\", null, \"Looking back at our Wikipedia definition:\"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"In computer science, functional programming is a programming paradigm-a style of building the structure and elements of computer programs-that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data\")), mdx(\"p\", null, \"\\u201CMathematical function\\u201D is just another term for the pure functions we\\u2019ve been looking at. Just like a math function, pure functions take an input and return a deterministic output using nothing but the input data.\"), mdx(\"p\", null, \"Mathematics: \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"f(x) = x * 2\")), mdx(\"p\", null, \"Javascript: \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"function f(x) { return x * 2 }\")), mdx(\"p\", null, \"The only difference is syntax!\"), mdx(\"p\", null, \"Alright, pure functions are great, but at some point we need to update state. So, where should we do it? Unfortunately, there isn\\u2019t a straightforward answer to this, and every situation will be a bit different. Later, we\\u2019ll see examples of common ways to avoid local state mutation by abstracting out code that mutates data into separate functions. Notice I didn\\u2019t say we got rid of mutation, I said we abstracted it out. This is a common way to write more \\u201Cimmutable\\u201D code. You don\\u2019t necessarily have to get rid of mutation, you just need to isolate it away from your program logic and make it reusable. A similar technique of isolating mutation is also common when managing global state in our programs. You may have heard of state management libraries like \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://redux.js.org/\"\n  }), \"Redux\"), \" or \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://pypi.org/project/taskflow/\"\n  }), \"Taskflow\"), \". These libraries take on the task of storing our global state, handling updates, and logging all data changes. These libraries are incredibly powerful tools that can help you write maintainable software.\"), mdx(\"hr\", null), mdx(\"h3\", {\n    \"id\": \"higher-order-functions\"\n  }, \"Higher-Order Functions\"), mdx(\"p\", null, \"A \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"higher-order function\"), \" is a function that does either/both of the following:\"), mdx(\"p\", null, \"1.) Accepts one or more functions as arguments\"), mdx(\"p\", null, \"2.) Returns a function\"), mdx(\"p\", null, \"Higher order functions (HOFs) are another useful tool to help write us write abstract and composable code. When our language lets us pass functions into other functions and return functions from functions we can create all sorts of super nice abstractions that decrease repetitive code and improve the readability of our programs.\"), mdx(\"p\", null, \"Example of a HOF:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"function do(action, input) {\\n    return action(input)\\n}\\n\")), mdx(\"p\", null, \"All our \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"do\"), \" function does is invoke the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"action\"), \" function passed to it with our \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"input\"), \" value. So, to make use of our \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"do\"), \" function we could write something like...\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"function increment(x) { \\n    return x + 1 \\n}\\nconsole.log(do(increment, 5)) // 6\\n\")), mdx(\"p\", null, \"Hopefully that example gave you some familiarity with HOFs. Now let\\u2019s look at a slightly more practical example:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"function greetWith(greeting) {\\n    return function(name) {\\n        return greeting + name\\n    }\\n}\\n\\nconst morningGreeting = greetWith(\\\"Good morning, \\\")\\n\\nconst students = [\\\"Samantha\\\", \\\"Kunal\\\", \\\"George\\\"]\\n\\nlet morningGreetings = [];\\n\\nfor(let i = 0; i < students.length; i++) {\\n    morningGreetings.push(morningGreeting(students[i]))\\n}\\n\\nconsole.log(morningGreetings) // [ \\\"Good morning, Samanatha\\\", \\n                              //   \\\"Good morning, Kunal\\\", \\n                              //   \\\"Good morning, George\\\" ]\\n\")), mdx(\"p\", null, \"Above we\\u2019ve created a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"greetWith\"), \" function that takes a single argument, \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"greeting\"), \", and returns a function that concatenates this greeting with a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"name\"), \". Taking a look at the line beneath our definition we can see how it's used. \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"morningGreeting\"), \" is set to the return value of \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"greetWith(\\\"Good morning, \\\")\"), \" which is our inner function that takes a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"name\"), \" argument. This technique is very common in the FP. It's so common that there is actually a name for it, currying. A more descriptive name that it often goes by is function specialization. All our outer function is doing is creating a specialized function based on the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"greeting\"), \" we provide it, and returning it. We can use the returned function exactly as you'd expect - we pass it a name, and it returns to us our full greeting string.\"), mdx(\"h4\", {\n    \"id\": \"never-write-a-for-loop-again-higher-order-functions-continued\"\n  }, \"Never write a for-loop again (higher order functions continued)\"), mdx(\"p\", null, \"Some of the most common code you\\u2019ll see in day-to-day programming is iterating over a list. Likely you will filter out certain data from the list, or manipulate each entry in the list. These operations are SO common that they\\u2019ve been abstracted into their own higher order functions. These are map, filter, and reduce. I've found that making use of these three functions is a good first step toward adopting a more functional style into your every day development. So, if there is one section of this post you should really pay attention to, it's this one!\"), mdx(\"p\", null, mdx(\"em\", {\n    parentName: \"p\"\n  }, \"Sidenote: The below code is all written in JS, but map, filter, and reduce are common patterns built into most programming languages.\")), mdx(\"h4\", {\n    \"id\": \"map\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"h4\"\n  }, \"map\")), mdx(\"p\", null, \"Map is a function that takes an array and an operation function. Map creates a new array and fills it with the results of calling the operation function on all of the original array entries.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const words = ['dog', 'plant', 'bike']\\n\\nfunction makePlural(word) {\\n    return word + 's'\\n}\\n\\nconst plurals = words.map(makePlural)\\n\\nconsole.log(words)   // ['dog', 'plant', 'bike']\\nconsole.log(plurals) // ['dogs', 'plants', 'bikes']\\n\")), mdx(\"p\", null, \"The \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"plurals\"), \" array is a copy of the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"words\"), \" array except that every entry has been thrown through our \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"makePlural\"), \" function. Here is a better way to visualize the creation of \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"plurals\"), \":\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const plurals = [\\n    makePlural('dog'),\\n    makePlural('plant'),\\n    makePlural('bike')\\n]\\n\")), mdx(\"p\", null, \"If \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"map\"), \" still feels too abstract that's ok. Something that really helped me understand \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"map\"), \" for the first time was seeing an implementation of it. It's important to remember that none of the functions you see here are magic. They can all be reimplemented using the programming language features you're already familiar with.\"), mdx(\"p\", null, \"Our own map implementation:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"function map(list, fn) {\\n    let result = []\\n    for(let i = 0; i < list.length; i++) {\\n        result[i] = fn(list[i])\\n    }\\n    return result;\\n}\\n\\n// Usage:\\nconst nums = [1,2,3]\\nfunction double(x) { return x * 2 }\\nconst doubled_nums = map(nus, double)\\nconsole.log(doubled_nums) // [2, 4, 6]\\n\")), mdx(\"p\", null, \"This code should look very familiar to you. It's just a simple for loop that updates a new array and returns it. One final note before we move on is that \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"map\"), \" does NOT mutate our old array - it creates a new one! (+1 for not mutating data)\"), mdx(\"p\", null, \"For more info on \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"map\"), \" in Javascript check the \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map\"\n  }), \"MDN Docs\")), mdx(\"h4\", {\n    \"id\": \"filter\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"h4\"\n  }, \"filter\")), mdx(\"p\", null, \"Another common process is extracting certain entries of a list into a new list (aka filtering out items). The filter function takes an array of items and a predicate function. Filter creates a new array and fills it with the elements of the original list that pass the predicate function test.\"), mdx(\"p\", null, \"Example:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const animals = [\\n    { name: 'keith', genus: 'lion' },\\n    { name: 'fluffy', genus: 'bear' },\\n    { name: 'norm', genus: 'tiger' },\\n    { name: 'lucy', genus: 'bear' },\\n    { name: 'rachel', genus: 'tiger' },\\n    { name: 'mittens', genus: 'lion' }\\n]\\n\\nfunction is_lion(animal) {\\n    return animal.genus === 'lion'\\n}\\n\\nconst lions = animals.filter(is_lion)\\n\\nconsole.log(lions)\\n=> [\\n    { name: 'keith', genus: 'lion' },\\n    { name: 'mittens', genus: 'lion' }\\n]\\n\")), mdx(\"p\", null, \"Filter is a pretty intuitive if you understand \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"map\"), \". It just iterates over your list and only adds entries to a new list if they pass your predicate function. For good measure though, let's write our own \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"filter\"), \" function.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"function filter(list, predicate) {\\n    let filtered_list = []\\n    for(let i = 0; i < list.length; i++) {\\n        if(predicate(list[i])) {\\n            filtered_list.push(list[i])\\n        }\\n    }\\n    return filtered_list\\n}\\n\\n// Usage\\nconst nums = [1, 2, 3, 4, 5]\\nfunction isEven(x) { return x % 2 === 0 }\\nconst evens = filter(nums, isEven)\\nconsole.log(evens) // [2, 4]\\n\")), mdx(\"p\", null, \"For more info on \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"filter\"), \" in Javascript check the \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Filter\"\n  }), \"MDN Docs\")), mdx(\"h3\", {\n    \"id\": \"reduce\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"h3\"\n  }, \"reduce\")), mdx(\"p\", null, \"Reduce (or fold as it is referred to in languages like Scala and Haskell) is another higher-order function for list iteration. This is the least intuitive of the three, but we'll get through it. The reduce function takes two arguments: a reducer function and an initial value. Each entry in the original array is passed through this reducer function to create a final value. Examples are the only way this will begin to make sense. \"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const nums = [12, 8, 22, 95]\\n\\nconst sum = nums.reduce(function(accumulator, currentValue) {\\n    return accumulator + currentValue\\n}, 0)\\n\")), mdx(\"p\", null, \"As mentioned above, our first argument to reduce is a function. Annoyingly enough this function is referred to as a reducer function. So, our reducER function takes an accumulator and a current value. For every entry in the array we'll call this function with an accumulator value and the array entry itself. Whatever is returned from the function will be the accumulator value for the next array entry (the accumulator value on the first item in the array will be our inital value I mentioned earlier). Once we've run out of array entries to process reduce will return our final accumulator value.\"), mdx(\"p\", null, \"Tracing through reduce is quite helpful, so here is what our accumulator and currentValue look like each time we invoke the reducer function.\"), mdx(\"p\", null, \"1.) \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"accumulator = 0, currentValue = 12\")), mdx(\"p\", null, \"2.) \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"accumulator = 0 + 12, currentValue = 8\")), mdx(\"p\", null, \"3.) \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"accumulator = 0 + 12 + 8, currentValue = 22\")), mdx(\"p\", null, \"4.) \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"accumulator = 0 + 12 + 8 + 22, currentValue = 95\")), mdx(\"p\", null, \"After executing our reducer for each member in our \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"nums\"), \" array, reduce will return our final value of: \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"0 + 12 + 8 + 22 + 95\"), \", or \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"137\"), \" for those of us that like our expressions reduced (ha).\"), mdx(\"p\", null, \"Implementation of reduce:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"function reduce(list, f, startVal) {\\n    let acc = startVal\\n    \\n    for(let i = 0; i < list.length; i++) {\\n        acc = f(acc, list[i])\\n    }\\n    \\n    return acc\\n}\\n\")), mdx(\"p\", null, \"For more info on \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"reduce\"), \" in Javascript check the \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce\"\n  }), \"MDN Docs\")), mdx(\"hr\", null), mdx(\"h3\", {\n    \"id\": \"writing-declarative-code\"\n  }, \"Writing Declarative Code\"), mdx(\"p\", null, \"What are the perks of using abstractions like \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"map\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"filter\"), \", and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"reduce\"), \",  aside from avoiding the strain of typing more? Are there any?\"), mdx(\"p\", null, \"Yes! Using these functions helps us in a couple of important ways:\"), mdx(\"p\", null, \"1.) Minimize code\"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"Writing less code means there is less code to debug. No more making mistakes in simple \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"for\"), \" loops. Remember, code is not an asset, it's a liability.\")), mdx(\"p\", null, \"2.) Code Readability\"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"Using abstractions in our code reduces the amount of code we have to read, and it also makes our programs more \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"declarative\"), \".\")), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"Declarative\"), \" code can be thought of as the opposite of imperative code. Instead of writing imperative programs where we show how each step in our logic works, we want to write declarative programs that \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"describes\"), \" what we're doing. \"), mdx(\"p\", null, \"Imperative - describes every step of the process. \"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"\\\"Shows how it is done\\\"\")), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const counts = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\\n\\nlet double_counts = []\\nfor(let i = 0; i < counts.length; i++) {\\n  double_counts[i] = counts[i] * 2\\n}\\n\")), mdx(\"p\", null, \"Declarative - Describes the end goal of our data. Accomplishes this by using abstractions around common procedures.\"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"\\\"Describes what is done.\\\"\")), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"function double(x) {\\n    return x * 2\\n}\\n\\nconst counts = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\\n\\nconst double_counts = counts.map(double)\\n\")), mdx(\"p\", null, \"When we write declarative code we're making our future lives MUCH easier. There is less code to comb through, it's simpler to read, and most importantly you don't have to \\\"be\\\" the computer to understand what is going on. Consider reading a piece of code that has multiple nested for loops. To really understand what is happening you have to \\\"become\\\" a computer and keep track of the all indexing logic in your head. Most of us can't do that effectively, or correctly for that matter. And even if you can, why waste the time? Investing time in writing more humanized programs is an effort you won't regret. Future you and your co-workers will really appreciate it.\"), mdx(\"p\", null, \"To wrap things up I wanted to give more examples of refactoring imperative code to be more functional. I think learning the laws of FP is just as important as learning how to apply them to real code. If you can't use these concepts in your day-to-day programming, then what's the use?\"), mdx(\"h3\", {\n    \"id\": \"refactoring-to-functional\"\n  }, \"Refactoring to Functional\"), mdx(\"p\", null, \"#####Block 1: (Greet the students) \"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"function greetWith(greeting) {\\n    return function(name) {\\n        return greeting + name\\n    }\\n}\\n\\nconst morningGreeting = greetWith(\\\"Good morning, \\\")\\n\\nconst students = [\\\"Samantha\\\", \\\"Kunal\\\", \\\"George\\\"]\\n\\nlet morningGreetings = [];\\n\\nfor(let i = 0; i < students.length; i++) {\\n    morningGreetings.push(morningGreeting(students[i]))\\n}\\n\\nmorningGreetings\\n=> [ \\\"Good morning, Samanatha\\\", \\n     \\\"Good morning, Kunal\\\", \\n     \\\"Good morning, George\\\" ]\\n\")), mdx(\"p\", null, \"#####Refactor of Block 1:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"function greetWith(greeting) {\\n    return function(name) {\\n        return greeting + name\\n    }\\n}\\n\\nconst morningGreeting = greetWith(\\\"Good morning, \\\")\\n\\nconst students = [\\\"Samantha\\\", \\\"Kunal\\\", \\\"George\\\"]\\n\\nconst morningGreetings = students.map(morningGreeting)\\n\\nmorningGreetings\\n=> [ \\\"Good morning, Samanatha\\\", \\n     \\\"Good morning, Kunal\\\", \\n     \\\"Good morning, George\\\" ]\\n\\n\")), mdx(\"p\", null, \"#####Block 2: (Find max element in list)\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const counts = [23, 15, 6, 79, 12]\\n\\nlet maxCount = -Infinity\\n\\nfor(let i = 0; i < counts.length; i++) {\\n    if(counts[i] > maxCount) {\\n        maxCount = counts[i]\\n    }\\n}\\n\\nmaxCount\\n=> 79\\n\")), mdx(\"p\", null, \"#####Refactor of Block 2\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"function max(x, y) {\\n    if(x > y) {\\n        return x;\\n    }\\n    return y;\\n}\\n\\nconst counts = [23, 15, 6, 79, 12]\\n\\nconst maxCount = counts.reduce(max, -Infinity)\\n\\nmaxCount\\n=> 79\\n\")), mdx(\"p\", null, \"#####Block 3: (create a new list containing incremented versions of the even numbers in the original list)\"), mdx(\"p\", null, \"Imperative\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const old_nums = [1,2,3];\\nlet new_nums = [];\\n\\nfor (let i = 0; i < old_nums.length; i++) {\\n  if (i % 2 == 0) {\\n    new_nums.push(old_nums[i] + 1);\\n  }\\n}\\n\\nnew_nums\\n=> [3, 5]\\n\")), mdx(\"p\", null, \"#####Refactor of Block 3\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"function increment(x) { return x + 1 }\\nfunction isEven(x) { return x % 2 == 0 }\\n\\nconst old_nums = [1, 2, 3, 4, 5]\\nconst new_nums = old_nums.filter(isEven).map(increment);\\n\\nnew_nums\\n=> [3, 5]\\n\")), mdx(\"h3\", {\n    \"id\": \"summary\"\n  }, \"Summary\"), mdx(\"p\", null, \"Functional programming is a paradigm of programming that can help us simplify our code. This is done by expressing our programs in terms of small, composable functions, applying a more declarative pattern to our code, and avoiding data mutation when possible. Although some of the concepts may be a bit difficult to grasp at first, the benefits of code readability, program simplicity, and easy debugging are well worth the effort. Our goal is not to write functional code - our goal is simplicity, and functional programming is the tool we're using to achieve it.\"), mdx(\"h4\", {\n    \"id\": \"more-resources\"\n  }, \"More Resources!\"), mdx(\"p\", null, mdx(\"em\", {\n    parentName: \"p\"\n  }, \"Below are links to articles and videos that helped me better understand the foundations of functional programming. So, if you want to learn more, I can't recommend these enough.\")), mdx(\"p\", null, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://maryrosecook.com/blog/post/a-practical-introduction-to-functional-programming\"\n  }), \"A Practical Introduction to Functional Programming\")), mdx(\"p\", null, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://medium.freecodecamp.org/higher-order-functions-in-javascript-d9101f9cf528\"\n  }), \"Higher Order Functions: Using Filter, Map and Reduce for More Maintainable Code\")), mdx(\"p\", null, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"http://www.lihaoyi.com/post/WhatsFunctionalProgrammingAllAbout.html\"\n  }), \"What's functional programming all about?\")), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"Talks/Video Playlists\")), mdx(\"p\", null, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.youtube.com/playlist?list=PL0zVEGEvSaeEd9hlmCXrk5yUyqUag-n84\"\n  }), \"Fun Fun Function (Functional Programming in Javascript)\")), mdx(\"p\", null, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.youtube.com/watch?v=e-5obm1G_FY&t=642s\"\n  }), \"Learning Functional Programming with JavaScript\")), mdx(\"p\", null, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.youtube.com/watch?v=m3svKOdZijA\"\n  }), \"Hey Underscore, You're Doing it Wrong!\")));\n}\n;\nMDXContent.isMDXComponent = true;"}},"pageContext":{"id":"fb25a3b1-75ac-554f-abcd-cfe246ba00c8"}}}