preface

Functional programming has been an eye-opening journey for me. This article, and others like it, are my attempt to share insights and perspectives as I explore the new realm of functional programming.

Ramda has always been my favorite FP library because it makes functional programming in JavaScript much easier. I highly recommend it.

Pipe

The concept of pipe is simple — it combines several functions. A pipe is a pipe that flows from left to right, with each function called from the output of the previous one.

getName = (person) = > person.name
getName({ name: 'Buckethead' })
// 'Buckethead'
Copy the code

Let’s write a function that capitalizes the string.

uppercase = (string) = > string.toUpperCase()
uppercase('Buckethead')
// 'BUCKETHEAD'
Copy the code

If we wanted the name of the Person object and capitalized it, we could write:

name = getName({ name: 'Buckethead' })
uppercase(name)
// 'BUCKETHEAD'
Copy the code

That’s good, but let’s get rid of the middle variable name.

uppercase(getName({ name: 'Buckethead' }))
Copy the code

A lot, but don’t like the way it’s nested. What if we wanted to add a function that gets the first six characters of a string?

get6Characters = (string) = > string.substring(0.6)
get6Characters('Buckethead')
// 'Bucket'
Copy the code

The result is this:

get6Characters(uppercase(getName({ name: 'Buckethead' })))
'BUCKET'
Copy the code

Let’s add another function to invert the string.

reverse = (string) = > string
  .split(' ')
  .reverse()
  .join(' ')
reverse('Buckethead')
// 'daehtekcuB'
Copy the code

Here’s what we see:

reverse(get6Characters(uppercase(getName({ name: 'Buckethead' }))))
// 'TEKCUB'
Copy the code

It can get a little too… More.

withpipeCome save us!

Instead of nested functions or creating a string of intermediate variables, pipe does all that!

pipe(
  getName,
  uppercase,
  get6Characters,
  reverse 
)({ name: 'Buckethead' })
// 'TEKCUB'
Copy the code

The art of simplicity. Looks like a to-do list!

Let’s go step by step.

For demonstration purposes, I’ll use the pipe implementation in functional Programming Articles by Eric Elliott.

pipe = (. fns) = > x= > fns.reduce((v, f) = > f(v), x)
Copy the code

I love this short one line of code.

We’re going to use rest arguments (the rest arguments), and as you can see from my article, we’re going to use PIPE to combine n functions. Each function takes the output of the previous one and is reduced to a single value.

You can use it as we did above.

pipe(
  getName,
  uppercase,
  get6Characters,
  reverse 
)({ name: 'Buckethead' })
// 'TEKCUB'
Copy the code

I will expand pipe and break a few breakpoints, line by line.

pipe = (. functions) = > (value) = > {
  debugger;
  return functions
    .reduce((currentValue, currentFunction) = > {
       debugger;
       return currentFunction(currentValue);
    }, value)
}
Copy the code

Use our example to call pipe and make something wonderful happen.

View local variables, functions are an array of four functions and value is {name: ‘Buckethead’}.

Now using the rest argument (again, see my related article here at 😁), PIPE allows us to use any number of functions, and it will loop through each of them.

In the next breakpoint, we use reduce internally, where currentValue is passed into currentFunction and returned.

We see Buckethead because currentFunction(getName) returns the name property of any object. This value will be returned to Reduce and will be changed to the new currentValue next time. Let’s continue to interrupt a little bit.

Now currentValues is Buckethead, because that’s what was returned last time. CurrentFunction is upperCase, so BUCKETHEAD will be the next currentValue.

Similarly, take the first six letters of BUCKETHEAD and place them in the next function.

Reverse ('. Aedi emaS) '

You’ve done it!

What is thecompose()?

The difference is just the direction of pipe.

So if you want the same result as the pipe above, you should reverse the order of the functions.

compose(
  reverse,
  get6Characters,
  uppercase,
  getName,
)({ name: 'Buckethead' })
Copy the code

Notice that getName is the last one in the chain and Reverse is the first one?

Here’s a quick implementation of Componse, also from the same article by the amazing Eric Elliott.

compose = (. fns) = > x= > fns.reduceRight((v, f) = > f(v), x);
Copy the code

This extended function breakpoint exercise is left for you to play with, use, and enjoy. Most of all, have fun!

The original link

A quick introduction to pipe() and compose() in JavaScript