Nathan-Wall / proto

A programming language derived from JavaScript which emphasizes prototypes, integrity, and syntax.
Other
12 stars 1 forks source link

Use `->` in destructuring #83

Closed Nathan-Wall closed 10 years ago

Nathan-Wall commented 10 years ago

I find the JS syntax for destructuring a little confusing:

var { a: b } = foo();

For some reason, it doesn't seem intuitive to me whether a or b is the property being renamed and which ones is the variable being declared. It can be even more confusing in nested destructurings:

var { x: { y: z } } = bar();

It would make it clear to use as instead of the colon:

var { a as b } = foo();
var { x as { y as z } } = bar();

Maybe?

traviskaufman commented 10 years ago

FWIW I've always liked the way scala does it:

import p.{x => a}   // the member x of p renamed as a.

This could translate to something like

var { a => b } = foo();
var { x => { y => z } } = bar();

I like it because - unlike the ES6 destructuring syntax - it specifies in clearly what is being renamed. I also like how it resembles the fat-arrow syntax, which to me makes sense as it can almost be viewed as the "projection" of one value onto another (even though it's just an alias).

For nested destructuring what about something like:

var { x.{y => z} } = bar();
traviskaufman commented 10 years ago

Oh, I see this is a proposal, not a question :) Either way I'll leave it up here as food for thought.

jwerle commented 10 years ago

+1 for as

Keep the arrow for lambdas On Jul 17, 2014 8:07 PM, "Travis Kaufman" notifications@github.com wrote:

Oh, I see this is a proposal, not a question :) Either way I'll leave it up here as food for thought.

— Reply to this email directly or view it on GitHub https://github.com/Nathan-Wall/proto/issues/83#issuecomment-49382057.

Nathan-Wall commented 10 years ago

@traviskaufman This is exactly what I want. I don't know the difference between "proposal" and "question", but I want "proposals" to be talked about and discussed if there are better solutions.

And I like the idea of using the arrow syntax for this. Like as, it's definitely a lot clearer than the colon about which is the property and which is the new variable being declared.

@jwerle, when you say to keep arrow for lambdas do you mean ES6-style arrow functions or something else? Proto actually doesn't need arrow for ES6 arrow functions because fn is so short using an arrow really doesn't get you anything. There's also a way to do implicit return to make it even shorter:

fn map(array, callback) :{
    return [:
        for u of array:
            each callback(u);
    ];
}

Using fn:

map([ 1, 2, 3, 4 ], fn(n) : n * 2);

Using an arrow:

map([ 1, 2, 3, 4 ], n => n * 2);

Arrows are nice, but they really don't get you that much over the existing fn. Plus, you can just as easily use gen or async for generator or arrow functions. So I removed the arrow syntax in 63569792277dea5350b272efe6fe980af04b2353.

However, when you said lambdas you might have meant something more like this. I have thought of using arrows for this (first class lambdas which preserve the meaning of return, continue, and break in the outer scope). Arrow would be a pretty nice fit for these, though I'm not sure that we should have them -- it may be too much having so many different kinds of callable things.

If we used => for destructuring, we could potentially use as for mutable bindings (a hot topic on es-discuss right now).

var foo = { a: 1, b: 2};
var { a => c, b as d } = foo;
// `d` is bound to `foo.b`
// while `c` only took the value of `foo.a`
foo.a = 3;
foo.b = 4;
c; // 1
d; // 4

Mutable bindings are wanted in ES for dealing with circular dependencies between modules. They're currently using the as keyword for this in import statements. We could do the same thing and also potentially generalize the idea for var. So it might be nice to have as available for this. But we could probably also come up with a different syntax if needed.

So I guess it comes down to whether we want to reserve => for possible use in pure first class block lambdas or if destructuring is a good use for the arrow.

I'm a bit split myself :-/

traviskaufman commented 10 years ago

I feel like you could get away with using arrows for both import statements and block lambdas, since the terminals surrounding the token are quite different depending on the case.

While I think as is okay, it seems that the grammar of proto is built around concise non-word symbols rather than keywords. Because of this I felt that arrows may be more appropriate, but then again I haven't looked at the language spec in a while.

Also what would you think of having -> for normal imports and => for mutable binding? Or perhaps the opposite since in ES6 => denotes that the receiver won't change, so you may want that to represent immutability. On the flip side of that it also represents a binding context, so it can also be viewed with the opposite argument of what was given above.

Nathan-Wall commented 10 years ago

@traviskaufman Perfect! I really like the idea of using -> as a regular renaming and => for mutable bindings.

var foo = { a: 1, b: 2 };
var { a -> x, b => y } = foo;
foo.a = 3;
foo.b = 4;
x; // 1
y; // 4
jwerle commented 10 years ago

+1 but I never find myself ever needing to do it for imports On Jul 18, 2014 7:53 PM, "Nathan Wall" notifications@github.com wrote:

@traviskaufman https://github.com/traviskaufman Perfect! I really like the idea of using -> as a regular renaming and => for mutable bindings.

var foo = { a: 1, b: 2 }; var { a -> x, b => y } = foo; foo.a = 3; foo.b = 4; x; // 1 y; // 4

— Reply to this email directly or view it on GitHub https://github.com/Nathan-Wall/proto/issues/83#issuecomment-49492320.

traviskaufman commented 10 years ago

awesome :)