How can I pipe functions in JS like Elm does?

javascript pipe function
javascript pipe map
elm function composition
what does pipe mean in javascript
typescript pipe function
elm anonymous function multiple arguments
js proposal pipe
javascript pipeline pattern

I'm just getting into functional programming and i'm having a hard time figuring out how to do this (if it's even worth the trouble). I've looked into currying and am not sure if this is the direction I need to go?? Or pipelines?

I would like to start with a value and then pipe it through different functions. Underscore has the 'chain' method which is similar. However I don't want to use prototypes to do this. I realize the solution might not match my target syntax.

Elm has the |> syntax (below) which is really nice to look at

// what i'd like to do (or similar) in JS *without using prototype*
num = ("(123) 456-7890")
  .removeDashes()
  .removeParens()
  .removeSpaces()

// what elm does
"(123) 456-7890"
  |> removeDashes
  |> removeParens
  |> rem


// functions I wrote so far

removeDashes = function(str) {
  return str.replace(/-/g, '');
};

removeParens = function(str) {
  return str.replace(/\(|\)/g, '');
};

removeSpaces = function(str) {
  return str.replace(/\s/g, '');
};


// what i'm currently doing

num =
  removeDashes(
    removeParens(
      removeSpaces(
        "(123) 456-7890"")));

There are different ways to tackle this problem, and you've offered references in underscore and Elm.

In Elm, curried functions are an important part of the equation. As every function receives a single argument, you can build chains with some of them partially applied, waiting for the argument you're weaving in with the pipeline. The same applies to Haskell, PureScript and languages of their ilk.

Reproducing that ipsis literis in JavaScript requires a little bit of sugar — you can use a sweet.js macro to get a source transformation that does it.

Without sugar, it can go many ways. Maybe one way to explore is using generators, passing the bits of the resolved chain down until you get a non-function value.

A simple explanation of functional pipe in JavaScript, So if we wanted to add a custom odds filter to array, we could do it like this: Array.​prototype.odds = function() { return this.filter(x => x % 2 === 1) }  Pipes.js Compose functions with Unix like pipes (like Elm / Elixir / F#) Using pipe operators makes you think about programming as steps of transformations. This compiler will replace the pipe operators with Lo-Dash's chain. Usage Define a function. These functions have no knowledge of the chaining system and can be used with or without chaining.

If you want to get you're feet wet with functional programming in JavaScript I'd advice you to use a library like Underscore, Lodash or Ramda. Which all have a compose/pipe functionality. Most of the times you'd want to combine it with some form of partial application which those libraries also provide.

Anyway it's a nice exercise to try to implement it yourself. I would solve it like this...

/* Asumes es5 or higher */

function pipe (firstFn /* ...restFns */) {
  var _ = null;
  var _slice = Array.prototype.slice;
  var restFns = _slice.call(arguments, 1) || [];


  return function exec_fns() {
    var args = _slice.call(arguments, 0, 1);

    return restFns.reduce(function(acc, fn) {
      return fn.call(_, acc);
    }, firstFn.apply(_, args));
  }
}

removeDashes = function(str) {
  return str.replace(/-/g, '');
};

removeParens = function(str) {
  return str.replace(/\(|\)/g, '');
};

removeSpaces = function(str) {
  return str.replace(/\s/g, '');
};


console.log(pipe(
  removeDashes,
  removeParens,
  removeSpaces
)("(123) 456-7890") == "1234567890")

Also Functional JavaScript by Fogus is a nice resource to dig deeper into this style of programming

Currying with Style in Elm - Alexander Boring, Put simply, currying is the technique of translating a function that takes Elm makes use of a pipe operator |> to chain together functions in an easy to look at compared to trying to accomplish similar tasks in Javascript, and I  Piping: Chaining functions. Of course return values can be used as arguments for subsequent function calls. In Elm there are two ways to chain the calls: Using the pipe-operators |> or <| one can pass through the result to the next function where it is used as the last argument for the function it gets piped into.

Like hindmost said, look into using prototypes. The string prototype allows you to add class-level functionality to all strings:

String.prototype.removeParens = function() {
    this = this.replace(/\(|\)/g, '');
}

This lets you do things like this:

var myString = "(test)";

myString.removeParens();

And once you add the other functions to the String prototype you can simply chain the function calls like this:

myString.removeDashes().removeParens().removeSpaces();

etc.

Elm Syntax, Elm Syntax. This syntax reference is a minimal introduction to: Comments; Literals; Lists; Conditionals; Records; Functions; Operators Modules; Type Annotations; Type Aliases; Custom Types; JavaScript Interop Historical note: this is borrowed from F#, inspired by Unix pipes. From JS, you talk to these ports like this: That is fine, and Elm does not need to know anything about it! Just send the strings through the relevant port. Notes. Ports are about creating strong boundaries! Definitely do not try to make a port for every JS function you need. You may really like Elm and want to do everything in Elm no matter the cost, but ports are not designed for that.

The easiest way is to really just add those to the prototype chain, but you can do that with an object. Here's an easy example:

function MyString( str ){
    var value = str.toString();

    return {
        removeDashes: function() {
            value = value.replace(/-/g, '');
            return this;
        },
        removeParens: function() {
            value = value.replace(/\(|\)/g, '');
            return this;
        },
        removeSpaces: function() {
            value = value.replace(/\s/g, '');
            return this;
        },
        toString: function (){
            return value;
        },
        valueOf: function (){
            return value;
        }
    };
}

You can later on do this:

var clean = (new MyString('This \\(Is)\/ Dirty'))
    .removeDashes()
    .removeParens()
    .removeSpaces();

This way, you will keep your prototype clean. To retrieve a non-object value, just run the toStrong() method, toValue() or do anything with the value (contatenating 1, divide it, anything!).

Function -, Before we do that, let's understand what a function is in mathematics first. Like if expression, we can assign the value returned by a function to a constant. Since that name is too long, the Elm community refers to it as the pipe operator. Data from JavaScript · Protecting Boundaries between Elm and JavaScript · Saving  When you use elm-reactor (or elm-make without any options) it generates a skeleton for you, consisting of some basic HTML and CSS, with a script tag containing your Elm code compiled to javascript. This is convenient but you will probably never use the HTML skeleton in a serious app.

Here's a solution I found with lodash, it allows you to mixin your own functions and then use them against chain:

...

removeSpaces = function(str) {
  return str.replace(/\s/g, '');
};

_.mixin({
  removeSpaces: removeSpaces,
  removeParens: removeParens,
  removeDashes: removeDashes
});

num = _.chain("(123) 456-7890")
  .removeSpaces()
  .removeParens()
  .removeDashes()
  .value()

AdamBrodzinski/pipes-js: Pipe operators in JS like Elm , Pipes.js. Compose functions with Unix like pipes (like Elm / Elixir / F#). Using pipe This compiler will replace the pipe operators with Lo-Dash's chain. You can define functions and use “destructuring assignment” in let expressions too. let ( three, four ) = ( 3 , 4 ) hypotenuse a b = sqrt (a^ 2 + b^ 2 ) in hypotenuse three four

Adding pipelines to JavaScript, And like their real-world counterparts, the output of one pipe can With a pipeline, we could do the same function like this: argumentToApply exist in a whole host of functional languages — Elm, Reason, Elixir, even Bash! Finally, in the main body of the function, you reach for the Phoenix module again to call Phoenix.push, which takes the socket url endpoint as a string and the Push Msg you specified in the let block as parameters. The Phoenix.push function returns a Cmd Msg. If you are unfamiliar with the Elm architecture,

Elm – functional frontend development • Dennis Reimann, Elm is a functional programming language that compiles to JavaScript. look like, how can functions be chained via piping and what the heck is currying? more. Motivation: I’m writing an Elm app, but I want to use Auth0’s JavaScript library. Elm does support JavaScript interop. It’s even documented! If you’re an Elm beginner, like me, the docs will leave you scratching your head. Here’s a more thorough example to get you started.

Using Elm to Write Better JavaScript Code, I recently had to write a fairly small piece of code in JavaScript. first solution took a fairly imperative approach but I did use some functional concepts like We then pipe that result into a function that sorts the transformed list. Can we do a nice transition instead? Redundant Requests. Each package has a single docs.json file, but it gets loaded each time you visit a module like String or Maybe. Can we share the data between pages somehow? Redundant Code. The home page and the docs share a lot of functions, like Html.text and Html.div. Can this code be shared between pages?

Comments
  • Add these functions to String's prototype. and you can call them in chain manner.
  • Chaining is completely different from functional programming.
  • @torazaburo yea I guess what I was looking for was piping not chaining. Lodash has a pipeline function that looks to be the closest
  • Ramda.js pipe or compose function can be used to do this activity. ramdajs.com/docs/#pipe
  • those macros are pretty slick! I ended up going with underscore's mixin and chain in my answer below. Close enough and I don't have to use this in the fns.
  • Assuming you are going to promote adding methods to the String prototype, you should at least do so with Object.defineProperty(String.prototype, 'removeParens', ...) so they don't end up being enumerable.
  • This works but I was looking for more of piping rather than chaining (my mistake)
  • This is interesting but for me it's less readable than just unpacking the parens. Thanks!
  • @SkinnyG33k I was just providing a different alternative. The versions using the prototype will work, but if something changes the prototype it can magle stuff up. Other than that, the prototype is superior.
  • I suppose this could be altered to allow pipe('(123) 456-7890')(removeDashes >> removeParens >> removeSpaces); //=> '1234567890', or possibly even to autocurry it to allow either style. But this has always felt more like a trick than like production code.
  • This works but I was looking for more of piping rather than chaining (my mistake)
  • @SkinnyG33k check stackoverflow.com/questions/20728460/…