tc39/proposal-object-rest-spread

Computed destructuring

maxhoffmann opened this issue · 3 comments

First of all thanks for this great proposal. I use it in production with Babel and it’s great.

I wondered if you considered “computed destructuring”, e.g.

let { [...properties], ...rest } = {}; 

I like that this keeps the symmetry of the assignment statement:

{ property: name, [ computed destructuring ], ...rest } = { property: value, [ computed property ], ...spread }

This would make implementing functions like lodash’s omit and pick trivial:

function omit(object, omitted) {
  let { [...omitted], ...rest } = object;
  return rest;
}

omit({ x: 1, y: 2, z: 3 }, ['x', 'z']) // { y: 2 }

function pick(object, picked) {
  let { [...picked], ...omitted } = object;
  let { [...Object.keys(omitted)], ...rest } = object;
  return rest;
}

pick({ x: 1, y: 2, z: 3 }, ['x', 'z']) // { x: 1, z: 3 }

It also opens up interesting possibilities, like declaring all exported properties of a common.js module in the module’s scope:

const { [...Object.keys(require('lodash'))] } = require('lodash');

typeof omit === 'function' // true

Maybe it’s possible to add “computed destructuring” to ES2015’s module syntax as well.

This came to my mind yesterday and I just wanted to ask if you have thought about this syntax already or if that’s even possible.

The "computed destructuring" you're talking about sounds like a giant, even more dangerous with statement to me. In sloppy mode, the last example could be accomplished with this:

with (require('lodash') {
  assert(typeof omit === 'function')
}

You could also accomplish similar by using combinators as well.

with (_.chain(obj).pairs().filter(func).zipObject().value()) {
  // what just got defined here? it's a black box... :-(
}

-1 from me.

pitaj commented
const { [...Object.keys(require('lodash'))] } = require('lodash');

This is scary. Like Isiah said, this is just a glorified with statement.
No, this is bad code. Imports and destructuring should be explicit, not calculated.

Yep, I agree now. This is not a good idea for JavaScript. Fortunately there are statically typed languages like Elm that mitigate the issue of name collisions of implicit imports.