Live data from Hacker News

Pipe Operator (|>) For JavaScript

github.com

241–250 of 437 posts

Re: Pipe Operator (|>) For JavaScript

#242
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…

> I also feel this: >> In the State of JS 2020 survey, the fourth top answer to “What do you feel is currently missing from JavaScript?” was a pipe operator. > Is the wrong way to go about language design. Let's call it Signor Rossi language design… "Signor Rossi cosa vuoi? … E poi, e poi, e poi" ( Viva la felicità by Franco Godi [1]) [1] https://www.youtube.com/watch?v=UrKKMtjNWCI

This and, they probably didn't mean the pipe operator from the niche language "hack".

Re: Pipe Operator (|>) For JavaScript

#243
post #169

Earlier quoted context omitted.

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.

Those variables help to document intent by naming the intermediate values. They also make step-debugging more convenient. In languages with type declarations, they also serve to inform about the type of the intermediate value, which otherwise is invisible in a pipe sequence.

Re: Pipe Operator (|>) For JavaScript

#245
post #169

Earlier quoted context omitted.

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.

This actually surprises me!

One habit introduced to my current team by a former co-worker involves having even more intermediate keys than that:

    const sensitiveEnv = [...];
    const envKeys = Object.keys(envars)
    const safeKeys = envKeys.filter(envar => !sensitiveEnv.includes(envar));
    const safeEnv = safeKeys.map(envar => `${envar}=${envars[envar]}`).join(' ');
    const styled = chalk.dim(`$ ${envStr}`, 'node', args.join(' '));
    console.log(styled);
In the beginning I wasn't a fan of it, as I do a lot of Haskell (and have point-free idioms on the tip of my fingers), and it's obviously unnecessary, as you said yourself. But with time I learned to appreciate this kind of function for its simplicity and consistence.

Now, of course, with a pipe operator (or other similar constructions) you can get the consistency without the intermediate names.

Re: Pipe Operator (|>) For JavaScript

#246

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 w…

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

That sounds like a fundamental mis-understanding. Variables do not hold objects, they hold references to objects.

    const foo = {};
    let bar = foo;
foo and bar hold references to the same object. They do not hold the object themselves. foo's reference can not be changed. It's const. bar's reference can. But the object is independent of both variables.

If you want the object itself to be unmodifiable there's Object.freeze.

    const foo ...
makes foo const. If you wanted a shortcut for making the object constant (vs Object.freeze) it would be something like

    let foo = new const SomeObject()
This doesn't exist but it makes more sense than believing that `const foo` some how makes the object constant. It only makes foo constant (the reference).

Re: Pipe Operator (|>) For JavaScript

#247
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 issue with taking examples from real-world code & converting them is that there's no guarantee the real-world code is good. It usually isn't, so you're comparing bad with bad. A more aggressive reformulation would be to prefix the original code with const envOutput = Object.keys(envars).map(envar => `${envar}=${envars[envar]}`).join(' '); const argsOutput = args.join(' '); Leaving the example being converted as s…

It's not jarring. It expresses what is the subject that's being processed and what are additional parameters of the processing steps. This allows to keep all parameters of each processing step together and processing steps easily visually separable.

Re: Pipe Operator (|>) For JavaScript

#248

Earlier quoted context omitted.

why? are you of a 'pointfree' opinion? what are your concerns? https://wiki.haskell.org/Pointfree personally i detest pointfree syntax. having intermediate values makes it much easier to step through code with a debugger & see what is happening. and it gives the reader some name for what the thing is, which is incredibly useful context. the enablement of pointsfree styles is one of my main concerns about potential pi…

I agree that (1) named intermediate values are sometimes more readable ... though I have examples where it's very hard to come up with names and not sure it helped (2) debugging is easier. For (2) though, this IMO is a problem with the debugger. The debugger should allow stepping by statement/expression instead of only by line (or whatever it's currently doing). If the debugger stopped at each pipe and showed in valu…

Intermediate variables also have the benefit to make not just the last value available in a debugger view, but also previous values (stored in separate variables). Of course, a debugger could remember the last few values you stepped through, but without being bound to named variables, presentation would be difficult.

Re: Pipe Operator (|>) For JavaScript

#249

Earlier quoted context omitted.

...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 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 something like this:

    |> `$1.indexOf($2)`
...whereas just sticking with the single `%` means you _can't_ disambiguate, and that if they instead try to allow disambiguation by deciding that the first `%` is `$1`, and the second `%` is `$2` (and so on), then now you can't use the template-string example I gave.

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

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?"

Post reply on HN