{"id":22895948,"url":"https://github.com/codewithreelofficial/functional-programming-javascript","last_synced_at":"2025-03-31T23:39:13.420Z","repository":{"id":260951792,"uuid":"142232993","full_name":"codewithreelofficial/functional-programming-javascript","owner":"codewithreelofficial","description":null,"archived":false,"fork":false,"pushed_at":"2018-08-22T04:12:47.000Z","size":89,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-07T01:45:47.413Z","etag":null,"topics":["functional-programming","javascript","javascript-functions"],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/codewithreelofficial.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-07-25T01:49:20.000Z","updated_at":"2019-07-13T18:48:34.000Z","dependencies_parsed_at":null,"dependency_job_id":"dae8141b-d755-41af-96fe-b0a2d39ef594","html_url":"https://github.com/codewithreelofficial/functional-programming-javascript","commit_stats":null,"previous_names":["codewithreelofficial/functional-programming-javascript"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codewithreelofficial%2Ffunctional-programming-javascript","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codewithreelofficial%2Ffunctional-programming-javascript/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codewithreelofficial%2Ffunctional-programming-javascript/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codewithreelofficial%2Ffunctional-programming-javascript/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/codewithreelofficial","download_url":"https://codeload.github.com/codewithreelofficial/functional-programming-javascript/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246558117,"owners_count":20796696,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["functional-programming","javascript","javascript-functions"],"created_at":"2024-12-13T23:32:54.277Z","updated_at":"2025-03-31T23:39:13.401Z","avatar_url":"https://github.com/codewithreelofficial.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Functional Programming Javascript\n\nFunctional programming is a way of writing clearner code through clever way of mutating, combinding, and using functions.\n\n## Arrow Functions (Fat Arrows)\n\nArrow functions create a concise expression that encapsulates a small piece of functionality. Additionally, arrows retain the scope of the caller inside the function eliminating the need of `self = this`.\n\nFor example:\n\n```javascript\n//  const multiply = function(x, y) {\n//    return x * y;\n//  }\n\n// Can be rewritten as:\n// const multiply = (x, y) =\u003e { return x * y };\n\n// Since the function is a single expression return and braces are not needed:\nconst multiply = (x, y) =\u003e x * y;\nconsole.log(multiply(5,10)) // 50\n```\n\n\u003ca href=\"https://codepen.io/Bunlong/pen/QBgdJb\" target=\"_blank\"\u003eEdit on Codepen\u003c/a\u003e\n\n## Scope\n\n* Global scope\n* Local scope\n* Function scope\n* Block scope\n* Function hoisting and scope\n* Functions do not have access to each other's scope\n* Nested scope\n\n**Global scope**\n\nIf a variable is declared outside all functions or curly braces `({})`, it is said to be defined in the global scope.\n\n```javascript\nconst globalVariable = 'some value';\n```\n\n## Closure\n\nClousure is the functions that have access to the parent scope, even when the parent function has closed.\n\nFor every closure there are 3 scopes: \n\n* Local scope ( Own scope) \n* Outer functions scope \n* Global scope\n\n## Function Delegates\n\nFunction delegates encapsulate a method allowing functions to be composed or passed as data.\n\nFor example:\n\n```javascript\nconst isZero = n =\u003e n === 0;\nconst a = [0, 1, 0, 3, 4, 0];\nconsole.log(a.filter(isZero)); // [0, 0, 0]\n```\n\n\u003ca href=\"https://codepen.io/Bunlong/pen/zLzNbd\" target=\"_blank\"\u003eEdit on Codepen\u003c/a\u003e\n\n## Expressions Instead of Statements\n\nStatements define an action and are executed for their side effect. Expressions produce a result without mutating state.\n\nFor example:\n\nStatement\n\n```javascript\nconst getSalutation = function(hour) {\n  var salutation; // temp value\n  \n  if (hour \u003c 12) {\n    salutation = \"Good Morning\";\n  } else {\n    salutation = \"Good Afternoon\"\n  }\n  \n  return salutation; // mutated value\n}\n\nconsole.log(getSalutation(10)); // Good Morning\n```\n\nExpression\n\n```javascript\nconst getSalutation = (hour) =\u003e hour \u003c 12 ? \"Good Morning\" : \"Good Afternoon\";\nconsole.log(getSalutation(10)); // Good Morning\n```\n\n\u003ca href=\"https://codepen.io/Bunlong/pen/mjwWeY\" target=\"_blank\"\u003eEdit on Codepen\u003c/a\u003e\n\n## Higher Order Functions\n\nA function that accepts another function as a parameter, or returns another function.\n\nFor example:\n\n```javascript\nfunction mapConsecutive(values, fn) {\n  let result = [];\n  \n  for(let i=0; i \u003c values.length -1; i++) {\n    result.push(fn(values[i], values[i+1]));\n  }\n  \n  return result;\n}\n\nconst letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];\nlet twoByTwo = mapConsecutive(letters, (x, y) =\u003e [x, y]);\nconsole.log(twoByTwo); // [[a, b], [b, c], [c, d], [d, e], [e, f], [f, g]]\n```\n\n\u003ca href=\"https://codepen.io/Bunlong/pen/JBJWRa\" target=\"_blank\"\u003eEdit on Codepen\u003c/a\u003e\n\n## Pure Functions\n\nA function that given the same input, will always return the same output. A pure function produces no side effects.\n\nNote: Side effects may include:\n\n* changing the file system\n* inserting a record into a database\n* making an http call\n* mutations\n* printing to the screen / logging\n* obtaining user input\n* querying the DOM\n* accessing system state\n\nFor example:\n\n```javascript\nvar xs = [1, 2, 3, 4, 5];\n\n// ==== pure ====\nxs.slice(0, 3);\n//=\u003e [1, 2, 3]\n\nxs.slice(0, 3);\n//=\u003e [1, 2, 3]\n\nxs.slice(0, 3);\n//=\u003e [1, 2, 3]\n\n// ==== pure ====\nxs.splice(0, 3);\n//=\u003e [1, 2, 3]\n\nxs.splice(0, 3);\n//=\u003e [4, 5]\n\nxs.splice(0, 3);\n//=\u003e []\n\n// pure\nvar checkAge = function(age) {\n  var minimum = 21;\n  return age \u003e= minimum;\n};\n\n// impure\nvar minimum = 21;\n\nvar checkAge = function(age) {\n  return age \u003e= minimum;\n};\n```\n\n\u003ca href=\"https://codepen.io/Bunlong/pen/OwOXzz\" target=\"_blank\"\u003eEdit on Codepen\u003c/a\u003e\n\n## Recursion\n\nRecursion is the ability to call a function from within itself.\n\nFor example:\n\n```javascript\nfunction countUp(n) {\n  console.log(n);\n  if(n \u003c 10) countUp(n+1);\n}\n\ncountUp(1);\n```\n\n\u003ca href=\"https://codepen.io/Bunlong/pen/zLPBPO\" target=\"_blank\"\u003eEdit on Codepen\u003c/a\u003e\n\n## Anonymous Functions\n\nAnonymous function is the function that was declared without any named identifier to refer to it.\n\nFor example:\n\n```javascript\n// Normal function\nfunction sayHi() {\n  alert('Hello world!');\n}\nsayHi();\n\n// Anonymous function assigned to sayHi variable\nvar sayHi = function() { \n  alert('Hello World!');\n}\n\n// Use as an argument to other functions\nsetTimeout(function() {\n  console.log('Hello World!');\n}, 1000);\n\n// Use as a closure\n(function() {\n  alert('Hello World!');\n})();\n\n// Use as a closure with parameters\n(function(msg) {\n  alert(msg);\n}('Hello World!'));\n\n// An anonymous function can refer to itself via arguments.callee local variable, useful for recursive anonymous functions\nconsole.log(\n  (function(n) {\n    return (1 \u003c n) ? arguments.callee(n - 1) + n : 1;\n  })(10)\n);\n\n// Instead of using arguments.callee, you can use named function expression instead\nconsole.log(\n  (function sum(n) {\n    return (n \u003c= 1) ? 1 : sum(n-1) + n\n  })(10)\n);\n```\n\n## Currying\n\nCurrying allows a function with multiple arguments to be translated into a sequence of functions. Curried functions can be tailored to match the signature of another function.\n\n```javascript\n// Statement\n// function convertUnits(toUnit = 0, factor, offset) {\n//   return function(input) {\n//     return ((offset + input) * factor).toFixed(2).concat(toUnit)\n//   }\n// }\n\n// Can be written as an expression\nconst convertUnits = (toUnit, factor, offset = 0) =\u003e input =\u003e ((offset + input) * factor).toFixed(2).concat(toUnit);\n\nconst milesToKm = convertUnits('km', 1.60936, 0);\nconst poundsToKg = convertUnits('kg', 0.45460, 0);\nconst farenheitToCelsius = convertUnits('degrees C', 0.5556, -32);\n\nconsole.log(milesToKm(10)); //\"16.09 km\"\nconsole.log(poundsToKg(2.5)); //\"1.14 kg\"\nconsole.log(farenheitToCelsius(98)); //\"36.67 degrees C\"\n\nconst weightsInPounds = [5, 15.4, 9.8, 110];\n\n// Without currying\n// const weightsInKg = weightsInPounds.map(x =\u003e convertUnits('kg', 0.45460, 0)(x));\n\n// With currying\nconst weightsInKg = weightsInPounds.map(poundsToKg);\nconsole.log(weightsInKg); // 2.27kg, 7.00kg, 4.46kg, 50.01kg\n```\n\n\u003ca href=\"https://codepen.io/Bunlong/pen/rrwmWR\" target=\"_blank\"\u003eEdit on Codepen\u003c/a\u003e\n\n## Array Manipulation Functions\n\nArray Functions are the gateway to functional programming in JavaScript. These functions make short work of most imperative programming routines that work on arrays and collections.\n\n***[].every(fn)***\n\nChecks if all elements in an array pass a test.\n\n***[].some(fn) | [].includes(fn)***\n\nChecks if any of the elements in an array pass a test.\n\n***[].find(fn)***\n\nReturns the value of the first element in the array that passes a test.\n\n***[].filter(fn)***\n\nCreates an array filled with only the array elements that pass a test.\n\n***[].map(fn)***\n\nCreates a new array with the results of a function applied to every element in the array.\n\n***[].reduce(fn(accumulator, currentValue))***\n\nExecutes a provided function for each value of the array (from left-to-right). Returns a single value, the accumulator.\n\n***[].sort(fn(a,b))*** warning, mutates state!\n\nModifies an array by sorting the items within an array. An optional compare function can be used to customize sort behavior. Use the spread operator to avoid mutation. [...arr].sort()\n\n***[].reverse()*** warning, mutates state!\n\nReverses the order of the elements in an array. Use the spread operator to avoid mutation. [...arr] . reverse()\n\nFor example:\n\n```javascript\nconst names = [\n  {text: \"Alpha\", value: 5}, \n  {text: \"Beta\", value: 2}, \n  {text: \"Gamma\", value: 4},\n];\n\n//Checks if all elements in an array pass a test.\nlet everyResult = names.every(x =\u003e x.value \u003e 0); //true\n\n// Checks if any of the elements in an array pass a test.\nlet someResult = names.some(x =\u003e x.text === \"Alpha\"); //true\n\n// Returns the value of the first element in the array that passes a test.\nlet findResult = names.find(x =\u003e x.text === \"Gamma\"); //{text: \"Gamma\", value: 4}\n\n// Creates an array filled with only the array elements that pass a test.\nlet filterResult = names.filter(x =\u003e x.value \u003e 3); //[{text: \"Alpha\", value: 5}, {text: \"Gamma\", value: 4}]\n\n// Creates a new array with the results of a function applied to every element in the array.\nlet mapResult = names.map(x =\u003e ({...x, value: x.value *10}));\n//[{text: \"Alpha\", value: 50}, {text: \"Beta\", value: 20}, {text: \"Gamma\", value: 40}];\n\n// Executes a provided function for each value of the array (from left-to-right). The returns a single value, the accumulator.\nlet reduceResult = names.reduce((accumulator, currentValue) =\u003e  currentValue.value \u003e accumulator.value ? currentValue : accumulator);\n// Get the largest object by value: {\"text\":\"Alpha\",\"value\":5}\n\n// Modifies an array by sorting the items within an array. An optional compare function can be used to customize sort behavior. Use the spread operator to avoid mutation. [...arr].sort()\nlet sortResult = [...names].sort((a,b) =\u003e b.value - a.value);\n\n// reverses the order of the elements in an array. Use the spread operator to avoid mutation. [...arr].reverse()\nlet reverseResult = [...names].reverse();\n\n// Results\nconst appDiv = document.getElementById('app');\nappDiv.innerHTML = `\n\u003cp\u003eevery: ${everyResult}\u003c/p\u003e\n\u003cp\u003esome: ${someResult}\u003c/p\u003e\n\u003cp\u003efind: ${JSON.stringify(findResult)}\u003c/p\u003e\n\u003cp\u003efilter: ${JSON.stringify(filterResult)}\u003c/p\u003e\n\u003cp\u003emap: ${JSON.stringify(mapResult)}\u003c/p\u003e\n\u003cp\u003ereduce: ${JSON.stringify(reduceResult)}\u003c/p\u003e\n\u003cp\u003ereverse: ${JSON.stringify(reverseResult)}\u003c/p\u003e\n\u003cp\u003esort: ${JSON.stringify(sortResult)}\u003c/p\u003e`;\n```\n\n## Method Chaining\n\nMethod chains allow a series of functions to operate in succession to reach a final result. Method chains allow function composition similar to a pipeline.\n\nFor example:\n\n```javascript\nlet cart = [\n  { name: \"Drink\", price: 3.12 }, \n  { name: \"Steak\", price: 45.15}, \n  { name: \"Drink\", price: 11.01}\n];\n\nlet drinkTotal = cart.filter(x=\u003e x.name === \"Drink\")\n                     .map(x=\u003e x.price)\n                     .reduce((t,v) =\u003e t + v)\n                     .toFixed(2); \n\nconsole.log(`Total Drink Cost $${drinkTotal}`); // Total Drink Cost $14.13\n```\n\n\u003ca href=\"https://codepen.io/Bunlong/pen/yqXbXQ\" target=\"_blank\"\u003eEdit on Codepen\u003c/a\u003e\n\n## Pipelines\n\nA pipeline allows for easy function composition when performing multiple operations on a variable. Since JavaScript lacks a Pipeline operator, a design pattern can be used to accomplish the task.\n\n```javascript\nconst pipe = functions =\u003e data =\u003e {\n  return functions.reduce(\n    (value, func) =\u003e func(value),\n    data\n  );\n};\n\nlet cart = [3.12, 45.15, 11.01];\nconst addSalesTax = (total, taxRate) =\u003e (total * taxRate) + total;\n\nconst tally = orders =\u003e pipe([\n  x =\u003e x.reduce((total, val) =\u003e total + val), // sum the order\n  x =\u003e addSalesTax(x, 0.09),\n  x =\u003e `Order Total = ${x.toFixed(2)}` // convert to text\n])(orders);\n\nconsole.log(tally(cart)); // Order Total = 64.62\n```\n\n\u003ca href=\"https://codepen.io/Bunlong/pen/qyjmPO\" target=\"_blank\"\u003eEdit on Codepen\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodewithreelofficial%2Ffunctional-programming-javascript","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodewithreelofficial%2Ffunctional-programming-javascript","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodewithreelofficial%2Ffunctional-programming-javascript/lists"}