JavaScript - Writing Functional Flows with Custom Pipes
Tags: javascript, function, beginners, tutorial
Published: 2023-10-17 19:43:55

##  

---

**_A very simple coding problem is often encountered early on_** in one's journey through programming, as it is a precursor to more interesting problems.  It usually reads something like this:  
> _Given an alphanumeric input of type {string},
write a function that returns a string in the reverse order_  

We'll use this familiar problem as the contrived basis for demonstrating the awesome possibilities of functional pipes.  

---

Now, some may well have gotten cozy with the use of slick libraries like [_ramda_](https://ramdajs.com/) and [_lodash_](https://lodash.com/), but perhaps fewer have a solid understanding of the mechanisms used.  


### The star player
We'll start by taking a patient look at the custom JavaScript pipe implementation that we'll use in the examples to come.  
I've also included a more traditional syntax for all the mustache heralds out there (let us know in the comments what syntax you prefer!):
```js
const pipe = 
     (...functions) =>
     (val) =>
        functions.reduce((prev, func) => func(prev), val);

// 
// OR
//

function pipeB(...functions) {
     return function(val) {
          return functions.reduce((prev, func) => {
               return func(val)
          }, val)
     }
};
```
>> _Those of us accustomed to writing Object-Oriented programs may find this syntax foreign.  It uses functional techniques like [currying](https://javascript.info/currying-partials) and [closures](https://engineering.cerner.com/blog/closures-and-currying-in-javascript/) that will allow us to wrap, or decorate, our other functions.  
The key operation, though, is the reduce that we call on our functions._

**Let's break this down a bit.**  
We can deduce that:
- The pipe accepts a series of functions and returns a function.
- That function accepts a value and returns a reduce function that we call on our series of functions.
- Every time our reducer iterates, one of our functions consumes the value and passes its output to the next function

---

**_What does all that do for us, then?_** 
So, every one of the functions that we supply to the pipe will consume our value in a step-by-step sequence, one after the other. Here's where the concept of a pipe and it's semantic exactness begins to wax into full shape.  
>> Imagining the purpose and form of a series of interconnected pipes, we can lay out a few functions with the expectation that they will be similarly pieced together:  
```js
const splitString = (string) => string.split("");
const reverseArray = (splitString) => splitString.reverse();
const joinArray = (reversedArray) => reversedArray.join(""); 
```
>> Now let's create a _custom flow_ with the pieces of our pipe:
```js
const reverseStrFlow = pipe(splitString, reverseArray, joinArray);
```
>> The result here is a new function that accepts a value,  so consuming our input will look like this:
```js
const reversedString = reverseStrFlow(stringToReverse);
```
>> Finally, here is our code all together with example i/o:
```js
const pipe = 
     (...functions) =>
     (val) =>
        functions.reduce((prev, func) => func(prev), val);

const splitString = (string) => string.split("");
const reverseArray = (splitString) => splitString.reverse();
const joinArray = (reversedArray) => reversedArray.join("");

const reverseStrFlow = pipe(splitString, reverseArray, joinArray);

const testString = "peloponnesian pumpkin";

const reversedString = reverseStrFlow(testString);
// expected output: "nikpmup naisennopolep"
```
**_For the record_**, one would rarely find meaningful need to write this much code for a problem slayable by a sexy one-liner:
`const reverseString = (string) => string.split("").reverse().join("")`
I only hope to diminish the _what_ in order to clarify the _how_:  
> **By flowing our value through a pipe made of functional pieces!**  

---

A key point in beginning to imagine the usefulness of this technique is to remember that we can create any number of custom pipes with any number of functional pieces that we need.  This makes the [composition](https://en.wikipedia.org/wiki/Function_composition_(computer_science)) of complex operations possible with less code.
The benefits of the compositional style are numerous:  

> ### Reusability  
>> Building in pieces allows for many possible unique combinations  
  
> ### Testability  
>> Test for simple inputs and outputs  

> ### Ease of debugging 
>> Smaller pieces, smaller problems  

> ### Avoid the pitfalls of [inheritance](https://www.learnhowtoprogram.com/react/functional-programming-with-javascript/the-problems-of-classical-inheritance)  
>> Ditch complex inheritance hierarchies that carry dead weight  

> ...and many more


---

Now that we've tantalized your tasters with some functional flavors, let's wrap things up with a final working example, this time with syntax highlighting:

### [Full Code on Repl](https://replit.com/@JoshuaDiehl/CurryPipe#index.js)

![Demonstration of making an abstract meal of chicken curry using pipe function](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r6reupxx8b7v8146m0iq.png)

---  
  
I'm honored if you've read this far ...  
Keep going, keep growing, and don't forget to have fun!

Until next time,
Joshua