Generalization of destructuring assignment, has this been discussed before?

# Lasse Reichstein (14 years ago)

Destructuring allows, e.g., var o = {}; [o.x, o.y] = [1, 2]; I.e., a generic LValue as a Field.

Could this be generalized to working outside of array/object braces in declarations, e.g.: var o.x = 42; // Declared non-configurable const o.x = 37; // Declared non-Wrtiable and non-configurable and the real reason for suggesting it, a highly convenient shorthand: function Foo.prototype.bar() { ... }

I think I have seen this suggested before, but it might just be Crockford's web pages at some point (perhaps the one suggesting "::" as abbreviation for ".prototype."). Has it been suggested for ES?

There doesn't seem to be any syntactic ambiguity (but it can foil look-ahead on functions if function calls are allowed as LValues, since "function foo()()()()()()()() { ... } " won't know which parenthesis starts the arguments until it sees the end of them).

Ofcourse, "classes" might remove the usecase for "in place function declaration" above.

# Brendan Eich (14 years ago)

On Sep 21, 2011, at 12:17 AM, Lasse Reichstein wrote:

Destructuring allows, e.g., var o = {}; [o.x, o.y] = [1, 2]; I.e., a generic LValue as a Field.

Could this be generalized to working outside of array/object braces in declarations, e.g.: var o.x = 42; // Declared non-configurable const o.x = 37; // Declared non-Wrtiable and non-configurable

o must denote an object already, right? Just checking -- some might want o if unbound to magically be bound to a fresh object, which would be deeply wrong.

and the real reason for suggesting it, a highly convenient shorthand: function Foo.prototype.bar() { ... }

This is an oldie, we talked about it in ES1 days, IIRC JScript supported (supports?) it.

I think I have seen this suggested before, but it might just be Crockford's web pages at some point (perhaps the one suggesting "::" as abbreviation for ".prototype."). Has it been suggested for ES?

"::" is wanted for guards. disnetdev.com/blog/2011/09/20/Contracts.coffee-Works-In-Node.js extends CoffeeScript to use :: for guard-ish contracts while leaving Coffee's use of :: intact. Yes, significant whitespace.

There doesn't seem to be any syntactic ambiguity (but it can foil look-ahead on functions if function calls are allowed as LValues, since "function foo()()()()()()()() { ... } " won't know which parenthesis starts the arguments until it sees the end of them).

I don't see how function foo()() is legal unless you are thinking of an extension such as ES4/JS1.8+ "expression closures" where the body can be an expression.

Ofcourse, "classes" might remove the usecase for "in place function declaration" above.

Sure, but I've never understood why people want to write

Foo.prototype.m1 = function (...){...}; Foo.prototype.m2 = function (...){...}; Foo.prototype.m3 = function (...){...}; ...

instead of

Foo.prototype = { m1: function (...){...}, m2: function (...){...}, m3: function (...){...}, ... };

The exact grammar for the dotted expression is unclear. Would you allow any member expression, even one with bracketed index expressions? Side effects? Where to draw the line?

In light of all this, I don't see a strong argument for allowing declarations to have dotted expressions instead of identifiers.

# Lasse Reichstein (14 years ago)

On Wed, Sep 21, 2011 at 10:27 AM, Brendan Eich <brendan at mozilla.com> wrote:

On Sep 21, 2011, at 12:17 AM, Lasse Reichstein wrote:

Destructuring allows, e.g., var o = {}; [o.x, o.y] = [1, 2]; I.e., a generic LValue as a Field.

Could this be generalized to working outside of array/object braces in declarations, e.g.: var o.x = 42; // Declared non-configurable const o.x = 37; // Declared non-Wrtiable and non-configurable

o must denote an object already, right? Just checking -- some might want o if unbound to magically be bound to a fresh object, which would be deeply wrong.

Agree, it must be an LValue, which in ES is any expression evaluating to a Reference (is this how LValue is meant in the destructuring proposal?). If o isn't declared, then o.x isn't a Reference (just a "ReferenceError" :), and if it's null or undefined, the Reference is there, but assignment will fail.

and the real reason for suggesting it, a highly convenient shorthand: function Foo.prototype.bar() { ... }

This is an oldie, we talked about it in ES1 days, IIRC JScript supported (supports?) it.

I think I have seen this suggested before, but it might just be Crockford's web pages at some point (perhaps the one suggesting "::" as abbreviation for ".prototype."). Has it been suggested for ES?

"::" is wanted for guards. disnetdev.com/blog/2011/09/20/Contracts.coffee-Works-In-Node.js extends CoffeeScript to use :: for guard-ish contracts while leaving Coffee's use of :: intact. Yes, significant whitespace.

Not suggesting to use ::, just trying to remember where I saw it :)

There doesn't seem to be any syntactic ambiguity (but it can foil look-ahead

on functions if function calls are allowed as LValues, since "function foo()()()()()()()() { ... } " won't know which parenthesis starts the arguments until it sees the end of them).

I don't see how function foo()() is legal unless you are thinking of an extension such as ES4/JS1.8+ "expression closures" where the body can be an expression.

The problem is that I was suggesting allowing function <any LValue>(x) {}

but in ES, a function call can return a Reference, so it would allow function foo(x)(x) {} which is both confusing and will cause the parser to need arbitrary lookahead in order to know which "(x)" are calls and which is the declaration. Using "const foo() {} " for declarations is actually even worse, so I guess there is an ambiguity.

Ofcourse, "classes" might remove the usecase for "in place function declaration" above.

Sure, but I've never understood why people want to write

Foo.prototype.m1 = function (...){...}; Foo.prototype.m2 = function (...){...}; Foo.prototype.m3 = function (...){...}; ...

instead of

Foo.prototype = { m1: function (...){...}, m2: function (...){...}, m3: function (...){...}, ... };

Needless adherence to tradition would require the prototype to have a .constructor property, so you have to write that too. I.e., I agree.

The exact grammar for the dotted expression is unclear. Would you allow any member expression, even one with bracketed index expressions? Side effects? Where to draw the line?

I would. And that's a good point. If it has side effects, when would those be evaluated? It seem that declarations on the form "function o.x(){}" would just be equivalent to "o.x = function x(){}" (except that it's not configurable). I.e., the saving is minuscule.

In light of all this, I don't see a strong argument for allowing declarations to have dotted expressions instead of identifiers.

I agree. There are too many corner cases, and not enough advantage.

# David Herman (14 years ago)

I've never liked these kinds of proposals because they confuse the declarative and imperative. Binding is static in JS (usually, anyway), and destructuring binding is a static form. If you introduce dotted forms you turn what looks like a binding form into purely a data-structure-mutating operation.