Live data from Hacker News

Pipe Operator (|>) For JavaScript

github.com

301–310 of 437 posts

Re: Pipe Operator (|>) For JavaScript

#301
post #27

Is this: Object.keys(envars) .map(envar => `${envar}=${envars[envar]}`) .join(' ') |> `$ ${%}` |> chalk.dim(%, 'node', args.join(' ')) |> console.log(%); Really better than: console.log(chalk.dim( `$ ${Object.keys(envars) .map(envar => `${envar}=${envars[envar]}`) .join(' ') }`, 'node', args.join(' ') )); That's the real-world example they have (I reformatted the second one slightly, because it looks better to me). N…

The thing I dislike about it most is the constantly-rebound % variable. It means something different in each line. In this case they have elected to keep it as a string throughout the pipe, but this ‘more pipey’ version of the code has it start out as an array then turn into a string halfway through the pipe, which feels dangerous (and is presumably why they didn’t take the example this far): Object.keys(envars) |> %…

Not really... F#-style pipeline syntax would be a bit more explicit about it, assuming you could use % for a variable name...

    Object.keys(envars)
      |> % => %.map(envar => `${envar}=${envars[envar]}`)
      |> % => %.join(' ')
      |> % => `$ ${%}`
      |> % => chalk.dim(%, 'node', args.join(' '))
      |> % => console.log(%);
To be honest, I've pretty much given up the hopes that TC39 would actually resolve pipelines and decorators at this point... I think it's been around a decade now.

Re: Pipe Operator (|>) For JavaScript

#302
post #27

Is this: Object.keys(envars) .map(envar => `${envar}=${envars[envar]}`) .join(' ') |> `$ ${%}` |> chalk.dim(%, 'node', args.join(' ')) |> console.log(%); Really better than: console.log(chalk.dim( `$ ${Object.keys(envars) .map(envar => `${envar}=${envars[envar]}`) .join(' ') }`, 'node', args.join(' ') )); That's the real-world example they have (I reformatted the second one slightly, because it looks better to me). N…

As somone that use to write a lot of functional-style code (in ruby), and generally prefers functional style, and have created many many many "pipelines" like that in ruby code - I've actually started to "regress" to "status-quo" (as the article puts it) mostly because I work with developers that don't understand functional style and it just becomes point of contention in review that I just don't care about getting into anymore. I can see this same kind of thing happening with this operator in JS-land (I may be wrong, haven't written any significant javascript in years, but people tend to be stubborn).

I just write things as stupidly as possible now, and just do the second one even though there are nicer "ruby-ways" to do them - maybe this is "bad" but I find it easy to read and grok...and it doesn't cause arguments during review <.<

Re: Pipe Operator (|>) For JavaScript

#303

Earlier quoted context omitted.

I struggle to think of real-world examples where I've just needed to chain and chain and chain values of different types more than a handful of times. The claimed need for the pipe operator is this construction: function bakeCake() { return separateFromPan(coolOff(bake(pour(mix(gatherIngredients(), bowl), pan), 350, 45), 30)); } The piped code looks like: function bakeCake() { return gatherIngredients() |> mix(%, bow…

In fact, I'm so fanatical about naming things, I'd probably give the two magic numbers and the return value names as well: function bakeCake() { const bakeTemperature = 450; const bakeTime = 45; // minutes // ... const bakedCake = bake(batterInPan, bakeTemperature, bakeTime); // ... const finishedCake = separateFromPan(cooledCake); return finishedCake; } And I'd not look at a code review which quibbled about the part…

Should make it an async function, and await the bake step. ;-)

Re: Pipe Operator (|>) For JavaScript

#304

Earlier quoted context omitted.

> ...so only the first usage of `%` counts as a replacement? Hopefully not because there’s no reason to: in the same way you can use + or - as prefix or infix, % as value and % as binary operator are not ambiguous. % % % should not be an issue, though it’s useless and not exactly sexy looking. > I'm surprised they aren't going with an idiom like `$1`, `$2`, etc That makes no sense, $1, $2, and $3 are different parame…

>That makes no sense, $1, $2, and $3 are different parameters. >Using your example, |> `${$3.id}: ${$1.friendlyName} ${$2.url}` >makes absolutely no sense. That's not what I was saying. I was saying that using `$1`, `$2`, and `$3` _would be different parameters, which would be good at helping disambiguate_. That would enable this, from my example: |> `${$1.id}: ${$1.friendlyName} ${$1.url}` while also enabling someth…

> That would enable this, from my example:

So the same thing except more verbose.

> while also enabling something like this:

Enable for what? A pipeline threads a value through a sequence of operation, there is no second parameter.

> ...whereas just sticking with the single `%` means you _can't_ disambiguate

Which doesn't matter because there is nothing to disambiguate.

> Having unique "magic scope variables" at least allows you the flexibility to handle non-unary use-cases.

Which do not and can not exist.

And even if they did (which, again, they don't), you could do exactly what Clojure does with its lambda shorthand: %1, %2, %3, %4.

> Either way, this is another case of "every lexer/parser has to be riddled with special cases" to handle "is this `%` a fancy-pipeline-identifier, or is it an operator?"

There is no special case, having the same character be a unary and binary operator is a standard feature of pretty much every parser. Javascript certainly has multiple, as well as operators which are both pre and post-fix.

Re: Pipe Operator (|>) For JavaScript

#305
post #53

Temporary variables are often tedious? I have found that well named temporary variables are the only clear way to comment code without actually writing the comment. The version with temporary variables is much easier to understand without having to read the rest of the code.

I think that depends on the context. Are all intermediate results of the application of multiple procedures relevant and need a name? Or are we only interested in the result after applying all the procedures? Why polute our namespace with names, which are never again used, except for the next step of the pipeline? Then in other cases one does need some intermediate results.

Re: Pipe Operator (|>) For JavaScript

#307
post #34

Can't wait for this. Pipes are awesome in Elixir and bringing them to JS/TS will be great. To me this is both concise and readable: const weather = `https://api.weather.gov/gridpoints/TOP/31,80/forecast` |> await fetch(%) |> await %.json() |> %.properties.periods[0]

That is concise, readable, and does not have any room at all for error handling. If this was Rust, it could at least be turned into something which returned the right Err for what was happening.

Without something like that, trying to add error handling to the things which may blow up would instantly turn it into gibberish. Every single function here can fail (the HTTP request could fail, the data returned could be unparseable as JSON, or not have the right format). We should be trying to make our languages encourage us to write code which can handle those errors naturally, rather than encouraging us to write fragile code.

Re: Pipe Operator (|>) For JavaScript

#308
post #128

Earlier quoted context omitted.

The F# syntax looks/acts a lot better here (especially paired with lodash). I also feel your code example wasn't done in the way people would actually use pipes. import {map, join} from 'lodash/fp' //iterators have better performance envars |> Object.entries |> map(([key, val]) => `${key}=${val}`) |> join(' ') |> x => chalk.dim('$ ' + x, 'node', join(' ', args)) |> console.log Even without lodash, it's still easy to…

The F# syntax would endlessly confuse me though. I'd always wonder whether |> join(' ') means join(x, ' ') or join(' ', x).

Your example wouldn't work as the function would need to be unary.

Re: Pipe Operator (|>) For JavaScript

#309
post #290

I wonder if "%" placeholder is the right approach. It makes the code longer in most cases. Without pipes: a = d(c(b)) With pipes in the proposed form: a = b|>c(%)|>d(%) My first approach to design it would be: a = b~>c~>d So the rule is that on the right side of the pipe operator (~>) there is always a function. We don't need parenthesis to indicate that. If the function takes more than one argument, it can be define…

Your ~> operator is effectively the F# style pipelines (using |>) that have already been rejected twice... Personally, I was fine with F# style myself... Hack style in TFA is also fine, not sure on `%` specifically though. In either case, I've lost hope of seeing either pipelines or decorators actually make it through committee in my lifetime at this point... it's been about a decade now.

Re: Pipe Operator (|>) For JavaScript

#310

That % syntax is just completely unlike anything else I have seen in JS. As a multi paradigm language, JS typically suffers from whatever programming style is on trend when these features are implemented. We are apparently on the other side of the pendulum now, but I can’t remember the last time I worked with a class and felt like that was right either.

We said the same things when arrow functions got introduced using an outlandishly un-javascripty syntax, as well as when templating strings got introduced using symbols that were the domain of LaTeX. Now they're "just what JS looks like" to both old and new JS devs. Look past the syntax, because you'll master it quickly enough and 2 years down the line forget it was ever not part of the language: does the actual func…

Working with something that uses an ES3-like level of the JS language, it's actually painful not having some of the conveniences added in the past decade+.
Post reply on HN