Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Object naming when using object destructuring #86

Closed
ceymard opened this issue Aug 20, 2011 · 18 comments
Closed

Proposal: Object naming when using object destructuring #86

ceymard opened this issue Aug 20, 2011 · 18 comments
Milestone

Comments

@ceymard
Copy link

ceymard commented Aug 20, 2011

As seen in another issue, the problem right now is that when using object destructuring in function arguments, it is impossible to access the base object (which is named _arg, _arg2, _arg3 at the moment).

The proposal is the following : ( { foo, bar } : baz, ... ) -> where baz replaces _arg.

Ideally, it should also work for assignment ; { argv } : optimist = require \optimist

@satyr satyr closed this as completed in cf02f1b Aug 20, 2011
@scribu
Copy link
Contributor

scribu commented Aug 20, 2011

Wouldn't it be possible to just use subdestructuring?

(baz{ foo, bar }) -> ...

And for assignment:

baz{ foo, bar } = y

if baz is out of scope, we could use:

baz{ foo, bar } := y

@ceymard
Copy link
Author

ceymard commented Aug 20, 2011

I actually like this idea better.

@scribu
Copy link
Contributor

scribu commented Aug 20, 2011

To clarify, convert the current syntax for subdestructuring:

from baz{ foo, bar } = y to baz{ foo, bar } := y

and the newly introduced named destructuring syntax:

from { foo, bar } : baz = y to baz{ foo, bar } = y

@satyr
Copy link
Owner

satyr commented Aug 20, 2011

How is giving subdestructuring and := context dependent behaviors better?
Note that you can mix subdestructuring with others (e.g. [a, b{c, d}] := e).

@ceymard
Copy link
Author

ceymard commented Aug 20, 2011

It's actually not so much a different behaviour, it's treating the baz part of baz{ foo, bar } as a regular variable.

If it doesn't exist in the local scope, it gets created. If used with :=, the check isn't made.

Right now, baz { a, b } = c translate to baz.a = c.a; baz.b = c.b. The proposal of scribu is to have a var baz declared before, and keep the current behaviour of baz { a, b } := c (which is actually the same that for =).

@ceymard
Copy link
Author

ceymard commented Aug 20, 2011

Maybe it would be better with example :

a{ b, c } = d
f = (b { d, e }) ->
    a{ d, e } := b

would give

var a = {}, f;
a.b = d.b; a.c = db.c;
f = function (b) {
    var d = b.d, e = b.e;
    a.d = b.d; a.e = b.e;
}

@satyr
Copy link
Owner

satyr commented Aug 20, 2011

it's treating the baz part of baz{ foo, bar } as a regular variable

baz can't be a non-variable, yup.

Maybe it would be better with example:

That example doesn't make sense:

  • a{b, c} => {a.b, a.c} need to hold on both sides of assignment.
  • (X) -> ... => (_arg) -> X = _arg; ... must hold.

@ceymard
Copy link
Author

ceymard commented Aug 20, 2011

Hm.

Current behaviour :

...
a{ y, x } = b
c{ y, x } := b
->
...
a.y = b.y, a.x = b.x;
c.y = b.y, c.x = b.x;

Proposed behaviour :

...
a{ y, x } = b
c{ y, x } := b
->
var a = {}; // on top of the scope.
...
a.y = b.y, a.x = b.x;
c.y = b.y, a.x = b.x;

Here, a can get modified a lot before coming to the statement a{ y, z } = b, and it will behave exactly like before.
The only difference is that a{ y, z } = has the same effect than a = as far as the existence of a is concerned in the current scope.

Anyways, the fact that using a{ y, z } = b and a{ y, z } := b produce the exact javascript code (while we are expressing two different things imo) is kind of strange.

@satyr
Copy link
Owner

satyr commented Aug 20, 2011

var a = {}; // on top of the scope.

How does this behavior relate to this issue? It seems entirely different proposal to me.

the fact that using a{ y, z } = b and a{ y, z } := b produce the exact javascript code (while we are expressing two different things imo) is kind of strange

The only difference between = and := is var generation. They behave identically when no variables are involved.

@ceymard
Copy link
Author

ceymard commented Aug 20, 2011

The only difference between = and := is var generation.

Precisely.

What is being suggested here is that instead of having a { a, b } : name construct only used in arguments, we could extend the whole issue to object destructuring in general ; we are just saying that baz { a, b } is like wanting to use the baz variable, with the added commodity of object destructuring.

Which has the implication of having the = and := operators behave like they would for variables (and so generate a var baz = {} on top of the scope -- since we know we're going to play with them as object).

As for the function arguments, just being in the arguments creates the variable in the local scope, so not much would have to change. (b{a, b}) -> would make function(b) { var a = b.a, b = b.b; }.

Another rationale for this request is that for now, using destructuration with = and := produce the exact same result, which is not very logical (why would two operators that have to distinct goals give the same result ? kind of a lost opportunity there)

@scribu
Copy link
Contributor

scribu commented Aug 20, 2011

The only difference between = and := is var generation. They behave identically when no variables are involved.

And when doing a{ y, z} = b, a isn't a variable??

@satyr
Copy link
Owner

satyr commented Aug 20, 2011

instead of having a { a, b } : name construct only used in arguments

It's not:

$ coco -bpe '{x, y}:o = f()'
var o, x, y;
o = f(), x = o.x, y = o.y;

In fact, it can't be a parameter-only feature; destructuring in parameters is merely an extension of normal assignment: (a) -> X = a => (X) -> where X is non-variable.

(b{a, b}) -> would make function(b) { var a = b.a, b = b.b; }.

For the reason I said above, this has to be:

$ coco -bpe '(b{a, b}) ->'
(function(_arg){
  b.a = _arg.a, b.b = _arg.b;
});

Another rationale for this request is that for now, using destructuration with = and := produce the exact same result

Again, not if you have a variable assignment in it:

$ coco -bpe '[a, b{c}] = d'
var a;
a = d[0], b.c = d[1].c;

$ coco -bpe '[a, b{c}] := d'
SyntaxError: assignment to undeclared variable "a" on line 1

And when doing a{ y, z} = b, a isn't a variable??

a is a variable, but that expression contains no variable assignments. It's property assignments (into a.y and a.z) via destructuring.

@scribu
Copy link
Contributor

scribu commented Aug 20, 2011

For the reason I said above, this has to be:

$ coco -bpe '(b{a, b}) ->'
(function(_arg){
  b.a = _arg.a, b.b = _arg.b;
});

With the proposed syntax, you couldn't automatically sub-destructure a function argument into an outer variable, like in your example, but I think that's a good thing.

a is a variable, but that expression contains no variable assignments.

I see, but why don't we make it into a variable assignment?

@satyr
Copy link
Owner

satyr commented Aug 20, 2011

I think that's a good thing

What about methods like (@{prop, prap}) ->? Exceptions to the proposed syntax?

why don't we make it into a variable assignment

I don't see the point.

@scribu
Copy link
Contributor

scribu commented Aug 20, 2011

What about methods like (@{prop, prap}) ->? Exceptions to the proposed syntax?

Yeah, that's tricky, especially with (@{prop, prap}) ~>.

The point would have been to have a more intuitive syntax for ({a, b} : x) -> but I guess it's not worth it.

@ceymard
Copy link
Author

ceymard commented Aug 20, 2011

I don't see the point.

I think it's about elegance. Honestly, baz{a,b} = foo is prettier than {a,b} : baz = foo.

What about methods like (@{prop, prap}) ->? Exceptions to the proposed syntax?

Yes. But then again, the this handling is generally tricky and kind of an exception itself in javascript.

@satyr
Copy link
Owner

satyr commented Aug 20, 2011

Also, how would you achieve:

$ coco -bpe 'x{z, y}:o = f()'
var o;
o = f(), x.z = o.z, x.y = o.y;

?

@ceymard
Copy link
Author

ceymard commented Aug 20, 2011

You don't anymore.

Alright. You win. :)

josher19 pushed a commit to josher19/LiveScript that referenced this issue Jul 24, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants