{"componentChunkName":"component---node-modules-gatsby-theme-chronoblog-src-templates-post-js","path":"/javascript-pipeline-operator/","result":{"data":{"mdx":{"id":"38e15004-837f-5e72-a9bb-6868731efc67","excerpt":"Javascript is getting a new operator! Maybe. A new operator is currently in stage 1 of the TC39 proposal process. Stage 1 is still early in…","frontmatter":{"title":"Javascript's New Pipeline Operator","date":"2020-01-06T00:00:00.000Z","description":null,"tags":["post","javascript"],"cover":null},"fields":{"slug":"/javascript-pipeline-operator/"},"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\": \"Javascript's New Pipeline Operator\",\n  \"date\": \"2020-01-06T00:00:00.000Z\",\n  \"tags\": [\"post\", \"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(\"p\", null, \"Javascript is getting a new operator! Maybe.\"), mdx(\"p\", null, \"A new operator is currently in stage 1 of the TC39 proposal process. Stage 1 is still early in the process, but getting to stage 1 means that it is being considered, and has an audience of developers pushing for it. If you have recently learned Javascript, or you\\u2019re still inexperienced with the language, you may be wondering what new operator Javascript could possibly need. It\\u2019s called a pipeline operator, and its necessity is definitely debateable. In this post, I want to give an overview of what the pipeline operator does, along with the positive and negative impacts of adopting it.\"), mdx(\"p\", null, mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"|>\")), mdx(\"p\", null, \"The operator shown above allows us to pipe a value through a chain of functions. Basic syntax support for the operator looks like this:\"), mdx(\"p\", null, mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"expression |> function\")), mdx(\"p\", null, \"To understand why this new operator is useful, it\\u2019s worth looking at a real example.\"), mdx(\"p\", null, \"Sidenote: you won\\u2019t be able to run this example in any JS engine currently available at the time of posting this article. You will need the pipeline operator \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://babeljs.io/docs/en/babel-plugin-proposal-pipeline-operator\"\n  }), \"babel plugin\"), \" (or similar transpiler tool) if you want to run these examples locally.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const double = x => x * 2\\n\\nconst num = 5\\nconst doubled_num = num |> double\\n\\nconsole.log(doubled_num) // 10\\n\")), mdx(\"p\", null, \"Looking at the above example, you may have come to the conclusion that this operator is pretty useless. In this particular example, you\\u2019re absolutely right. We could have just as easily invoked the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"double\"), \" function and passed it our \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"num\"), \" constant. The code below gets us the same output, and it\\u2019s easier to understand.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const doubled_num = double(num)\\n\\nconsole.log(doubled_num) // 10\\n\")), mdx(\"p\", null, \"Admittedly, this operator does JUST invoke functions, but it becomes much more useful with longer pipelines.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const name = \\\"charles\\\"\\n\\nconst greet = name => `Hello, ${name}`\\n\\nconst capitalize = str => str.toUpperCase()\\n\\nconst exclaim = str => `${str}!!!`\\n\\nconst loudGreeting = name \\n                      |> greet\\n                      |> capitalize\\n                      |> exclaim\\n\\nconsole.log(loudGreeting) // HELLO, CHARLES!!!\\n\")), mdx(\"p\", null, \"Here is what that code would look like without the pipeline operator.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const name = \\\"charles\\\"\\n\\nconst greet = name => `Hello, ${name}`\\n\\nconst capitalize = str => str.toUpperCase()\\n\\nconst exclaim = str => `${str}!!!`\\n\\nconst loudGreeting = exclaim(capitalize(greet(name)))\\n\\nconsole.log(loudGreeting) // HELLO, CHARLES!!!\\n\")), mdx(\"p\", null, \"Even in a trivial example like this, you can see that the pipeline operator offers better readability. With the pipeline operator, I\\u2019m able to read the operations in the order they are executed from top to bottom instead of unraveling an onion of nested function calls in my head. Although the syntax is new, the idea of piping values through multiple operations is not. This functionality exists in many other languages, and shows up inside nearly every JS helper function library like \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://underscorejs.org/\"\n  }), \"underscore\"), \" and \", mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://ramdajs.com/\"\n  }), \"ramda\"), \".\"), mdx(\"h3\", {\n    \"id\": \"do-we-need-the-pipeline-operator\"\n  }, \"Do we need the pipeline operator?\"), mdx(\"p\", null, \"Being someone who would use it in my own development, I still consider this operator a \\u201Cnice to have\\u201D. I\\u2019ve been using this same functionality for a couple of years now with Ramda\\u2019s compose and pipe functions, and they don\\u2019t cause me any trouble. In the rare case where I absolutely can\\u2019t import third-party libraries, I can always write my own piping functionality in a few lines of code.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const pipe = (...fns) => (input) => {\\n  return fns.reduce((acc, f) => {\\n    return f(acc)\\n  }, input)\\n}\\n\\n// referring to the earlier example\\nconst loudGreeting = pipe(greet, capitalize, exclaim)(name)\\n\\nconsole.log(loudGreeting) // HELLO, CHARLES!!!\\n\")), mdx(\"p\", null, \"The native pipeline operator does separate itself in some ways from third-party library pipeline helpers. The pipeline operator will support many Javascript specific syntaxes and language features like generators and async/await. Having baked-in support for features unique to JS is definitely a perk of adopting the new operator.\"), mdx(\"h3\", {\n    \"id\": \"is-there-a-downside-to-adding-the-operator\"\n  }, \"Is there a downside to adding the operator?\"), mdx(\"p\", null, \"Personally, I would enjoy using the new operator. It provides a cleaner way to express function composition and is a feature supported in many other popular languages. I think if Javascript were created in 2020, the operator should absolutely be a part of the language. However, that isn\\u2019t the case. Javascript is a matured language used by millions of developers. Adding new features like this comes at a cost \\u2014 it adds complexity to THE most popular programming language in the world. Sure, this single new operator probably won\\u2019t cause anyone headaches, but this isn\\u2019t the only operator addition to Javascript in the past few years, and it won\\u2019t be the last. Generators, object/array destructuring, async/await, classes, arrow functions, etc. Although these are all great to work with and improve the language, it\\u2019s hard not to feel bad for new programmers entering the JS world.\"), mdx(\"p\", null, \"Javascript was already difficult to learn when I started, but I can\\u2019t imagine learning it today. It feels like Javascript has gone through a BC and AD era, and for beginners, it\\u2019s very difficult to figure out what\\u2019s old and what\\u2019s new. Obviously, it\\u2019s not impossible to learn it, but I sympathize with beginners reading multiple tutorials that tell them to do the same thing in multiple different ways. With an increasingly complex language like Javascript, I have to believe a lot of new programmers are losing interest early on because they can\\u2019t MAKE something without struggling for hours to understand which function syntax they should use. I don\\u2019t think this is a reason for the language to stop progressing, but I think it needs to be considered before we continue over-saturating the language with new functionality.\"), mdx(\"p\", null, \"The barrier to entry for self-taught developers is getting higher, and adding new operators for minor convenience is a contributor.\"), mdx(\"hr\", null), mdx(\"p\", null, \"For more information, examples, and updates on the new pipeline operator check out these resources \\uD83D\\uDE00\"), mdx(\"p\", null, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Pipeline_operator\"\n  }), \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Pipeline_operator\")), mdx(\"p\", null, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://github.com/tc39/proposal-pipeline-operator\"\n  }), \"https://github.com/tc39/proposal-pipeline-operator\")));\n}\n;\nMDXContent.isMDXComponent = true;"}},"pageContext":{"id":"38e15004-837f-5e72-a9bb-6868731efc67"}}}