8000 Feature Request: pipeline function because people want a pipe operator since 2020 · Issue #5962 · lodash/lodash · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
Feature Request: pipeline function because people want a pipe operator since 2020 #5962
< 8000 div class="Box-sc-g0xbh4-0 ehzXEi">
Open
@paulftw

Description

@paulftw

tc39/proposal-pipeline-operator made the hack pipe cool again.
If, when, and in what shape it is going to get through is an open question, but lodash can deliver pretty much the same fun with one simple function.

Consider the above proposal's main usage example:

  Object.keys(envars)
    .map(envar => `${envar}=${envars[envar]}`)
    .join(' ')
    |> `$ ${%}`
    |> chalk.dim(%, 'node', args.join(' '))
    |> console.log(%);

Almost same "coding experience" can be achieved utilizing modern JS features (not so modern as of 2025):

  // async is omitted for brevity, see below
  const pipeline = (initial, ...lambdas) =>
      lambdas.reduce((acc, fn) => fn(acc), initial)
  
  pipeline(
    Object.keys(envars)
      .map(envar => `${envar}=${envars[envar]}`)
      .join(' '),
    $ => `$ ${$}`,
    $ => chalk.dim($, 'node', args.join(' ')),
    $ => console.log($),  
  )

With lodash.pipeline one could literally:

  1. copy-paste any snippet from tc39/proposal-pipeline-operator
  2. replace all occurrences of % with $ or _ (one even has freedom to choose their personal favorite)
  3. replace |> with $ =>
  4. add trailing comas
  5. wrap everything in a pipeline(...) call.

It can be done today, without waiting for TC39 decision, browser and tooling support, etc.

Only downside versus the proposal I could think of so far is apparently it cannot support yield.
I'm not sure if and how well the proposal will implement yield, maybe others can weigh in.

Sample implementation I've offered above doesn't work for async code, async-aware version would look like this:

const pipeline = async (initial, ...lambdas) =>
    lambdas.reduce(async (acc, fn) => fn(await acc), initial)

Open questions I hope others would weigh in on:

  1. Should it be called pipeline or pipe or else? (with this approach we get rid of the proposal's % bikeshedding, so let's bikeshed this one instead)
  2. In case of sync code await is redundant. Is it that bad for performance? Is it a big enough reason not to go this route?
    • I think not, but if yes, what about having sync and async versions...
  3. Can anything be done about yield? I see it so rarely in the wild, not sure when it shines.
  4. Am I missing something obvious?

What do you guys think?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0