Live data from Hacker News

Pipe Operator (|>) For JavaScript

github.com

161–170 of 437 posts

Re: Pipe Operator (|>) For JavaScript

#161
post #70

Earlier quoted context omitted.

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.

Nested calls can be a code smell, sure. But easily fixable: one(two(three())); Becomes let a=three(); let b=two(a); one(b); Clean and easy, no sugar required.

Lots of low-value names required. Those names will inevitably either be badly chosen or have taken far more time to make up than they are worth. That's assuming the code isn't written by that one guy on every team who stubbornly insists on

   var x = three();
   x = two(x);
   one(x):
(having the names certainly is nice to have in the debugger, but I'd rather have those intermediate results be an explicit debugger feature than junk taking up mental bandwidth all over the code, at all times)

Re: Pipe Operator (|>) For JavaScript

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

[deleted]

Re: Pipe Operator (|>) For JavaScript

#163

Earlier quoted context omitted.

% % 2 Gross

...so only the first usage of `%` counts as a replacement? What if I need the value to be replaced multiple times, like this: |> `${%.id}: ${%.friendlyName} ${%.url}` I'm surprised they aren't going with an idiom like `$1`, `$2`, etc or something like in other languages that have "magic" lambda parameters.

> ...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 parameters.

Using your example,

    |> `${$3.id}: ${$1.friendlyName} ${$2.url}`
makes absolutely no sense.

Not to mention the very minor issue that $1 is already a valid JS identifier.

> or something like in other languages that have "magic" lambda parameters.

% is one of those, it’s what closure uses for its lambda shorthand. Scalia uses `_` and kotlin uses `it`.

The latter two are ambiguous but I guess since pipes are new syntax there wouldn’t be a huge issue making them contextual keywords.

Most language with “pipelines” are curried so it’s not a concern, and in the rest it tends to be a fixed-form insertion, so it’s quite inflexible, but in both cases APIs are designed so they play well with that limitation e.g. in curried language you’d have the “data” item last (that’s obviously in Haskell), which also allows for partial application in general, while in “macro” languages, well, it depends where you decide the magical argument should be inserted (IIRC in Elixir it’s the first, so functions written for pipe compatibility should take the main operation subject first).

Clojure is cool because it has both plus a macro where you give it the name of the substituted symbol. However being a lisp the pipe macros are still prefix, not infix.

Re: Pipe Operator (|>) For JavaScript

#164
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).

The top example relies on Lodash/fp having curried functions you can use.

The middle example would be using native stuff which is why you have the wrapper function (kinda like you'd have a function wrapping a callback)

Re: Pipe Operator (|>) For JavaScript

#165
post #3

They should have stuck with the F# proposal. The hack proposal just takes one more giant step toward turning JS into Perl. Hack proposal value |> foo(%) for unary function calls, value |> foo(1, %) for n-ary function calls, value |> %.foo() for method calls, value |> % + 1 for arithmetic, value |> [%, 0] for array literals, value |> {foo: %} for object literals, value |> `${%}` for template literals, value |> new Foo…

Wouldn't it be better to use '->' as the operator? This is about dataflow so an arrow would represent that nicely. Whereas '|>' doesn't really "mean" anything. An arrow means that something flows in the direction of the arrow.

Not only that but I can't be the only person who finds -> vastly easier to type than |>.

Re: Pipe Operator (|>) For JavaScript

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

The version with temp variables is also easier to debug.

Re: Pipe Operator (|>) For JavaScript

#167
Saw a talk with Douglas Crockford[0] years ago. He said something like: Before JS classes got introduced he asked why they didn't just implement macros for the language. Classes are in fact just syntactic sugar. Just like async/await, and now this proposal.

In hindsight he was right. JS would be better off if it did have macros. Much of the whole babel/webpack/react/ts stuff would be just a bunch of macros instead of idiosyncratic build tools and so on. And we would have had much less compatibility churn.

In fact this proposal here, is trivial to implement with macros. Clojure has the same thing (threading operator) and it's just a macro.

[0] https://en.wikipedia.org/wiki/Douglas_Crockford

Re: Pipe Operator (|>) For JavaScript

#168
post #40

JavaScript isn't that kind of programming language. I don't know why people are constantly trying to make it something else.

Javascript is, without exaggeration (and with much chagrin), the language that has done more to popularize functional programming than any other programming language in history. It's only natural that they'd continue pushing on that front. :P

This was by accident though.

Re: Pipe Operator (|>) For JavaScript

#169

Earlier quoted context omitted.

the refactored version of the example is much worse

Do you mind elaborating? I find the refactored version significantly easier to understand than the original. Readability is one of the top priorities for me and I find the original example too clever, in a bad way.

I dislike variables that are used just once. Sometimes they're a "necessary evil", but rarely. For "envStr" it's defensible IMHO as it splits up some of the complexity, but I would rather just use a helper function, which has the same "splits complexity" effect and is re-usable.

"styled" seems entirely pointless here.

Re: Pipe Operator (|>) For JavaScript

#170

Earlier quoted context omitted.

A problem is that you can only declare intermediate constants in a statement context, not an expression context. And with React, more and more JS devs are spending time in expression contexts Example: return ( {foo(bar(stuff))} ) There's no way to break out inline intermediate constants here; you have to bail out and do it up above the `return`. In this case that may not be too bad, but when you've got a hundred line…

But that's a symptom of issues with React, not issues with JavaScript. React's declarative model makes it easy to write unreadable spaghetti React declarations that are nested ten levels deep. Nobody should be adding features to JavaScript to encourage that. ("Please, I'm begging you, for the love of sanity... Refactor into more than one component. Just one time. Look, functional components even make that cheap and e…

Highly disagree on two counts:

> that's a symptom of issues with React, not issues with JavaScript

IMO keeping as much as possible in an expression-context is preferable, even without React, because it simplifies control-flow and avoids mutation. The main problem in this case, as I see it, is that javascript doesn't fully support that style- it could and should have a feature that allows intermediate constants (but not variables!) inside expressions. (It should also have something better than ternaries for expressive conditionals, but that's a separate topic)

> Refactor into more than one component

Plenty of ink has been spilled here in the past about splitting functions when there's a real conceptual boundary, not just when they "get too large", and how otherwise keeping your code together in one place can actually make it easier to follow because you don't have to jump around all over the place. So I don't really want to get into all that again here, but suffice to say that's my stance on the subject.

Post reply on HN