Live data from Hacker News

Pipe Operator (|>) For JavaScript

github.com

131–140 of 437 posts

Re: Pipe Operator (|>) For JavaScript

#131
post #13
post #8

Earlier quoted context omitted.

The current JS one isn't as nice as the Elixir one, at least it wasn't when I tried using it via Babel a couple yrs ago.

The JS one does seem to have some more power than the Elixir one. For instance, in Elixir, if it's a bit kludgy to pipe to a second or third argument. I find this often when I want to insert into a map. You can always define more functions, but otherwise it's annoying, because you end up with something like computation() |> &(Map.put(my_map, key, &1)).() That said, with this less-power, you do kind of end up forced t…

As I mentioned upthread, most Elixir functions are designed to have the thing they operate on as first argument.

    computation() |> &(Map.put(my_map, key, &1))
is terrible style when

    Map.put(my_map, key, computation())
works just as well and is more readable. It is pretty rare to have a pipeline that needs to insert the value elsewhere than the first position. And please, do not write single element pipelines, I see them far too often from Elixir beginners.

Re: Pipe Operator (|>) For JavaScript

#132
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.

Exactly. As the proposal contemplates this alternative, it claims:

> But there are reasons why we encounter deeply nested expressions in each other’s code all the time in the real world, rather than lines of temporary variables.

And the reason it gives is:

> It is often simply too tedious and wordy to write code with a long sequence of temporary, single-use variables.

Sorry, but...that's the job? If naming things is too hard and tedious, you don't have to do it, I guess, but you've chosen a path of programming where you don't care about readability and maintainability of the codebase into the future. I don't think the pipe operator magically rescues the readability of code of this nature.

The tedium of coming up with a name is a forcing function for the author's brain to think about what this thing really represents. It clarifies for future readers what to expect this data to be. It lets your brain forget about the implementation of the logic that came up with the variable, so as you continue reading through the rest of the code your brain has a placeholder for the idea of "the envVar string" and can reason about how to treat it.

The proposal continues:

> If naming is one of the most difficult tasks in programming, then programmers will inevitably avoid naming variables when they perceive their benefit to be relatively small.

Programmers who perceive the benefit of naming variables to be relatively small need to be taught the value of a good name, and the danger of not having a good name, not given a new bit of syntax to help them avoid the naming process altogether.

The aphorism "There are two hard problems in computer science: cache invalidation, and naming things." is not an argument to never cache and never name things. That's mostly what we software folks spend our time doing, in one way or another.

Re: Pipe Operator (|>) For JavaScript

#133
I don't understand why you can't just use temporary variables. The article mentions mutation is bad, but what actually happens is that the name gets reassigned. No value is mutated.

That brings me to something I really want in JS, actual unmutable values. If you use `const x = new SomeClass()`, you cannot reassign it, but you can change fields. The first time I encountered `const`, I thought it did the opposite. It would be cool if you could declare something (object, array) to be an immutable value.

If you really want to introduce new operators, how about operator overloading? For example vector and matrix calculations become a lot clearer and less error-prone with infix operators. It should be technically easy to add them to typescript - rewrite the expression to a function call depending on the types of the operands - but the TS devs refuse to implement this on philosophical grounds unless it is implemented in JS. I guess in JS it would require runtime dispatch, but maybe that is not such a big penalty given that it usually uses a JIT anyway.

Oh, and while we are at it, fix `with`. The JS with statement is ridiculous and deprecated anyway. It makes all fields of an object available in it's scope. Contrast with VB6's `with`, which requires you to use a leading dot and is much more readable:

    with (elem.style) {
        .fontFamily = 'Arial';
        .color = 'red';
        console.log(.borderWidth);
        // in actual JS this would just be
        // console.log(borderWidth);
    }

Re: Pipe Operator (|>) For JavaScript

#134
post #52

Earlier quoted context omitted.

TC39 proposals often have rubbish real world examples that should never see the light of day in a JS codebase. It makes me really question the judgement of the people that are working on this language, and it explains how some of the shittier proposals manage to slip in and why the good ones are misused all over the place in every real world codebase when this is the kind of guidance devs have on where to use fancy n…

> TC39 proposals often have rubbish real world examples that should never see the light of day in a JS codebase. This example was literally taken directly from real-world code in the React codebase (a script to call jest-cli). While you're correct that there are probably a lot of clearer and more readable ways to write this snippet, the fact of the matter remains that people write code exactly like these "real world…

Yes and those people with a proven track record of writing awful code will now have another new tool to apply their valuable skills with. I can't wait.

Re: Pipe Operator (|>) For JavaScript

#135

> three(two(one(value))) const oned = one(value); const twoed = two(oned); const threed = three(twoed); This proposition goes out of its way to find problems with code that is written in a confusing and uncommon way in the first place.

It's annoying to have to decide on and write out so many names. The intermediary names are not relevant to solving the problem. This is so much less noisy: value |> one |> two |> three

It's only less noisy because of the simplistic nature of the example. In real world code, `one`, `two` and `three` and probably a chunk of code put together in a single line and it's difficult to find out what the hell they are doing. Concat together a few of these and that's a recipe for disaster. Less experienced engineers would add a comment at the top of the pipe chain explaining what's going on. More experienced engineers would divide and conquer and use temporary named variables (render commets useless).

Re: Pipe Operator (|>) For JavaScript

#136
post #70

Earlier quoted context omitted.

Indeed. The argument of “nested calls are hard to read” is strange, because this looks terrible

Anything looks better than nested calls once you have started to get used to the benefits of reading left-to-right. It's one of those pains you don't realize you have unless it suddenly goes away.

I don't see how moving the actual thing that's returning (and it returns "toward" the left) all the way to the right end of the expression—as far away from the assignment, if any, as possible—improves readability.

Re: Pipe Operator (|>) For JavaScript

#137
post #84

This strikes me as something better left to libraries. If you want to write in a functional style then Ramda, Lodash, Underscore, and plenty of others have pipe and compose functions. pipe(one, two, three) Easy to read. No new syntax. Extendable with arrow functions. Yes, there are some limitations in comparison to Hack Pipes. But those are far outweighed by not messing yet again with the language’s syntax.

For me limitations are killing 90% of usecases.

In absence of |> % syntax I'd nearly always would go with intermediate temporary variables instead of pipe(). "point-free" syntax feels horrible for me and wrapping everything in lambdas feels excessive.

Re: Pipe Operator (|>) For JavaScript

#138

This just complicates things if you have any kind of complex nesting. Something "simple" like: a(b(),c(),d(e(),f(g()))) Turns into the following: value |> b() |> a( %, c() , v2 |> e() |> d(%, v1 |> g() |> f(%) ))

Not to mention the confusion of nested percent vars

Re: Pipe Operator (|>) For JavaScript

#139
post #64
post #52

Earlier quoted context omitted.

TC39 proposals often have rubbish real world examples that should never see the light of day in a JS codebase. It makes me really question the judgement of the people that are working on this language, and it explains how some of the shittier proposals manage to slip in and why the good ones are misused all over the place in every real world codebase when this is the kind of guidance devs have on where to use fancy n…

I am still hoping that decorators might not pan out :fingers-crossed:

Wait, what's wrong with decorators? They seem pretty nice in python.

Re: Pipe Operator (|>) For JavaScript

#140
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 Hack proposal is horrible imo because it doesn’t look like JS anymore. The F# proposal is 99% of the benefit whilst being actually approachable.

> The Hack proposal is horrible imo because it doesn’t look like JS anymore.

I mean it looks exactly like JS with an additional % placeholder.

Post reply on HN