Pipe expression

# Artem Kobzar (4 years ago)

When we need to me destruction from array or object and change value then we need make something like this

let { first, second } = getSomeObject();
first = computeFirst(first);

// Or create temporary useless variable

const obj = getSomeObject();
const second = obj.second;
const first = computeFirst(obj.first);

I propose to make operator which will give ability to us to apply some function to property inside destruction-syntax without mutable or temporary variables

const { first | computeFirst, second } = getSomeObject();

I think that syntax should be discussed, but it seems lie pipe-symbol is well-known operator in bash and in AngularJS/Vue community.

# James Wright (4 years ago)

(Just realised I forgot to reply all! Whoops!)

Can't we just use destructuring defaults for this, given it seems that both V8 and SpiderMonkey lazily invoke functions in this context? I haven't corroborated this with the spec though, so I could be wrong.

const log = name => fn => (...args) => console.log('Calling', name) ||

fn(...args); const getFirst = log('getFirst')(() => 'manual first!');

const getSomeObject = () => ({ second: 'second' });

const getFullObject = () => ({ first: 'real first!', second: 'second' });

(() => {   // first is already defined, thus getFirst() isn't called   let { first = getFirst(), second } = getFullObject(); })();

(() => {   // logs 'Calling getFirst'...   let { first = getFirst(), second } = getSomeObject(); })();

We can prove this with a simpler example:

const getThing = () => {   console.log('called');   return 1; };

(() => {   let { x = getThing() } = { x: 1 }; })(); // Logs nothing // <= undefined

(() => {   let { x = getThing() } = {}; })(); // Logs 'called' // <= undefined

I appreciate that one could pipe /n/ functions with your proposal, but personally I'm not sure this necessitates new syntax.

# Cyril Auburtin (4 years ago)

They could indeed use, or should say abuse defaut values:

const { first, firstComputed = computeFirst(first), second }
= getSomeObject();

but that's confusing, error-prone

do-expressions are quite verbose

const { first, second } = do { const { first, second } = getSomeObject();
({ first: computeFirst(first), second }) }

So I think having 2 lines is bearable, more clear/readable:

const { first, second } = getSomeObject();
const firstComputed = computeFirst(first);

Or refactor your computeFirst function to accept an object (({first, ...rest}) => {/*...*/ return {first: something, ...rest}})

const { first, second } = computeFirst(getSomeObject());