Pipe expression
(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.
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());
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.