(x) => {foo: bar}

classic Classic list List threaded Threaded
50 messages Options
123
Reply | Threaded
Open this post in threaded view
|

(x) => {foo: bar}

Frankie Bagnardi
let f = (x) => {foo: bar};

In the implementations I checked, this is actually allowed, but it's parsed as a label instead of what you may expect at first glance (an object).

Is there any reason this is allowed?  If there's no reason other than to match function(){}, this should be a syntax error, in my opinion.

A potentially easier and wider reaching solution here would be to restrict labels in strict mode to demand a possible break/continue, else it's a syntax error.  The only area I'd be concerned about compatibility is low level generated JavaScript.

Thoughts?

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: (x) => {foo: bar}

Caitlin Potter
In the implementations I checked, this is actually allowed, but it's parsed as a label instead of what you may expect at first glance (an object).

For it to be a concise body, you need to change it to `let f = (x) => ({foo: bar});`. Otherwise, it's like a regular function body.

On Mon, Jan 5, 2015 at 2:02 PM, Frankie Bagnardi <[hidden email]> wrote:
let f = (x) => {foo: bar};

In the implementations I checked, this is actually allowed, but it's parsed as a label instead of what you may expect at first glance (an object).

Is there any reason this is allowed?  If there's no reason other than to match function(){}, this should be a syntax error, in my opinion.

A potentially easier and wider reaching solution here would be to restrict labels in strict mode to demand a possible break/continue, else it's a syntax error.  The only area I'd be concerned about compatibility is low level generated JavaScript.

Thoughts?

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: (x) => {foo: bar}

Calvin Metcalf
this seems like a footgun and has tripped people up in the wild https://twitter.com/jankrems/status/544645776518184960

On Mon Jan 05 2015 at 2:05:52 PM Caitlin Potter <[hidden email]> wrote:
In the implementations I checked, this is actually allowed, but it's parsed as a label instead of what you may expect at first glance (an object).

For it to be a concise body, you need to change it to `let f = (x) => ({foo: bar});`. Otherwise, it's like a regular function body.

On Mon, Jan 5, 2015 at 2:02 PM, Frankie Bagnardi <[hidden email]> wrote:
let f = (x) => {foo: bar};

In the implementations I checked, this is actually allowed, but it's parsed as a label instead of what you may expect at first glance (an object).

Is there any reason this is allowed?  If there's no reason other than to match function(){}, this should be a syntax error, in my opinion.

A potentially easier and wider reaching solution here would be to restrict labels in strict mode to demand a possible break/continue, else it's a syntax error.  The only area I'd be concerned about compatibility is low level generated JavaScript.

Thoughts?

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: (x) => {foo: bar}

Brendan Eich-2
See

http://wiki.ecmascript.org/doku.php?id=strawman:block_vs_object_literal

This could be done, but not for ES6. Sorry I didn't push this harder,
earlier.

/be

Calvin Metcalf wrote:

> this seems like a footgun and has tripped people up in the wild
> https://twitter.com/jankrems/status/544645776518184960
>
> On Mon Jan 05 2015 at 2:05:52 PM Caitlin Potter
> <[hidden email] <mailto:[hidden email]>> wrote:
>
>     > In the implementations I checked, this is actually allowed, but
>     it's parsed as a label instead of what you may expect at first
>     glance (an object).
>
>     For it to be a concise body, you need to change it to `let f = (x)
>     => ({foo: bar});`. Otherwise, it's like a regular function body.
>
>     On Mon, Jan 5, 2015 at 2:02 PM, Frankie Bagnardi
>     <[hidden email] <mailto:[hidden email]>> wrote:
>
>         let f = (x) => {foo: bar};
>
>         In the implementations I checked, this is actually allowed,
>         but it's parsed as a label instead of what you may expect at
>         first glance (an object).
>
>         Is there any reason this is allowed?  If there's no reason
>         other than to match function(){}, this should be a syntax
>         error, in my opinion.
>
>         A potentially easier and wider reaching solution here would be
>         to restrict labels in strict mode to demand a possible
>         break/continue, else it's a syntax error.  The only area I'd
>         be concerned about compatibility is low level generated
>         JavaScript.
>
>         Thoughts?
>
>         _______________________________________________
>         es-discuss mailing list
>         [hidden email] <mailto:[hidden email]>
>         https://mail.mozilla.org/listinfo/es-discuss
>
>
>     _______________________________________________
>     es-discuss mailing list
>     [hidden email] <mailto:[hidden email]>
>     https://mail.mozilla.org/listinfo/es-discuss
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

RE: (x) => {foo: bar}

Domenic Denicola
What do you think the chances of this are in ES7+? That is, how backward-compatible is this change? The linked strawman doesn't seem to touch on `() => { foo: bar }` as a back-compat hazard. Do you feel hopeful?

-----Original Message-----
From: es-discuss [mailto:[hidden email]] On Behalf Of Brendan Eich
Sent: Monday, January 5, 2015 14:41
To: Calvin Metcalf
Cc: es-discuss
Subject: Re: (x) => {foo: bar}

See

http://wiki.ecmascript.org/doku.php?id=strawman:block_vs_object_literal

This could be done, but not for ES6. Sorry I didn't push this harder, earlier.

/be

Calvin Metcalf wrote:

> this seems like a footgun and has tripped people up in the wild
> https://twitter.com/jankrems/status/544645776518184960
>
> On Mon Jan 05 2015 at 2:05:52 PM Caitlin Potter
> <[hidden email] <mailto:[hidden email]>> wrote:
>
>     > In the implementations I checked, this is actually allowed, but
>     it's parsed as a label instead of what you may expect at first
>     glance (an object).
>
>     For it to be a concise body, you need to change it to `let f = (x)
>     => ({foo: bar});`. Otherwise, it's like a regular function body.
>
>     On Mon, Jan 5, 2015 at 2:02 PM, Frankie Bagnardi
>     <[hidden email] <mailto:[hidden email]>> wrote:
>
>         let f = (x) => {foo: bar};
>
>         In the implementations I checked, this is actually allowed,
>         but it's parsed as a label instead of what you may expect at
>         first glance (an object).
>
>         Is there any reason this is allowed?  If there's no reason
>         other than to match function(){}, this should be a syntax
>         error, in my opinion.
>
>         A potentially easier and wider reaching solution here would be
>         to restrict labels in strict mode to demand a possible
>         break/continue, else it's a syntax error.  The only area I'd
>         be concerned about compatibility is low level generated
>         JavaScript.
>
>         Thoughts?
>
>         _______________________________________________
>         es-discuss mailing list
>         [hidden email] <mailto:[hidden email]>
>         https://mail.mozilla.org/listinfo/es-discuss
>
>
>     _______________________________________________
>     es-discuss mailing list
>     [hidden email] <mailto:[hidden email]>
>     https://mail.mozilla.org/listinfo/es-discuss
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: (x) => {foo: bar}

Brendan Eich-2
Domenic Denicola wrote:
> What do you think the chances of this are in ES7+? That is, how backward-compatible is this change? The linked strawman doesn't seem to touch on `() =>  { foo: bar }` as a back-compat hazard.

The strawman discusses compatibility explicitly:

http://wiki.ecmascript.org/doku.php?id=strawman:block_vs_object_literal#compatibility

"""

This proposal is mostly backward-compatible. In particular, the “stray
label” problem whereby

javascript:foo()

migrates from URL contexts (links, |src| attribute values, the browser’s
address toolbar) into script content, but not at the start of a block,
continues to work. Note that such a “label” is not used by the statement
or expression to which it is affixed.

Useless labels are thus allowed other than at the start of a block
(immediately after the |*{*| that starts the block).

A block in JS today, or a block-lambda
<http://wiki.ecmascript.org/doku.php?id=strawman:block_lambda_revival>
if that extension is supported, may be prefixed by a label and actually
use that label, e.g. via a |break| targeting that label. The grammar
changes above support such a label-using block(-lambda).

"""

>   Do you feel hopeful?

Reasonably.

How often is label-after-block-opening-left-curly used and actually
useful? Empirical question, where did Google codesearch go? :-/. Arrows
won't change answer much, my guess, by the time ES7 is going.

/be
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: (x) => {foo: bar}

Caitlin Potter
In reply to this post by Domenic Denicola
The strawman changes to the grammar are still ambiguous :(

`() => {}` -> noop or Object or SyntaxError? If SyntaxError, ...why?

I think hacking around this would not get rid of the footgun, but would just make it more complicated to understand the footgun, personally.


On Mon, Jan 5, 2015 at 2:46 PM, Domenic Denicola <[hidden email]> wrote:
What do you think the chances of this are in ES7+? That is, how backward-compatible is this change? The linked strawman doesn't seem to touch on `() => { foo: bar }` as a back-compat hazard. Do you feel hopeful?

-----Original Message-----
From: es-discuss [mailto:[hidden email]] On Behalf Of Brendan Eich
Sent: Monday, January 5, 2015 14:41
To: Calvin Metcalf
Cc: es-discuss
Subject: Re: (x) => {foo: bar}

See

http://wiki.ecmascript.org/doku.php?id=strawman:block_vs_object_literal

This could be done, but not for ES6. Sorry I didn't push this harder, earlier.

/be

Calvin Metcalf wrote:
> this seems like a footgun and has tripped people up in the wild
> https://twitter.com/jankrems/status/544645776518184960
>
> On Mon Jan 05 2015 at 2:05:52 PM Caitlin Potter
> <[hidden email] <mailto:[hidden email]>> wrote:
>
>     > In the implementations I checked, this is actually allowed, but
>     it's parsed as a label instead of what you may expect at first
>     glance (an object).
>
>     For it to be a concise body, you need to change it to `let f = (x)
>     => ({foo: bar});`. Otherwise, it's like a regular function body.
>
>     On Mon, Jan 5, 2015 at 2:02 PM, Frankie Bagnardi
>     <[hidden email] <mailto:[hidden email]>> wrote:
>
>         let f = (x) => {foo: bar};
>
>         In the implementations I checked, this is actually allowed,
>         but it's parsed as a label instead of what you may expect at
>         first glance (an object).
>
>         Is there any reason this is allowed?  If there's no reason
>         other than to match function(){}, this should be a syntax
>         error, in my opinion.
>
>         A potentially easier and wider reaching solution here would be
>         to restrict labels in strict mode to demand a possible
>         break/continue, else it's a syntax error.  The only area I'd
>         be concerned about compatibility is low level generated
>         JavaScript.
>
>         Thoughts?
>
>         _______________________________________________
>         es-discuss mailing list
>         [hidden email] <mailto:[hidden email]>
>         https://mail.mozilla.org/listinfo/es-discuss
>
>
>     _______________________________________________
>     es-discuss mailing list
>     [hidden email] <mailto:[hidden email]>
>     https://mail.mozilla.org/listinfo/es-discuss
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: (x) => {foo: bar}

Brendan Eich-2
Caitlin Potter wrote:
> The strawman changes to the grammar are still ambiguous :(
>
> `() => {}` -> noop or Object or SyntaxError? If SyntaxError, ...why?

No, the strawman addresses this: "An empty pair of braces |*{}*| other
than at start of /Statement/ is an /ObjectLiteral/." The grammar is
unambiguous. Notice the meta-? in the first production RHS below, and
the non-empty-producing nature of the second:

Block:
     { UnlabeledStatementFirstList? }
     { WellLabeledStatement StatementList? }

UnlabeledStatementFirstList:
     UnlabeledStatement
     UnlabeledStatementFirstList Statement


The final piece of the puzzle is here:

We retain the |[lookahead ∉ {*{*, *function*}]| restriction in
/ExpressionStatement/. At the start of a statement, |*{*| can be the
start of a block only, never an object literal.

> I think hacking around this would not get rid of the footgun, but
> would just make it more complicated to understand the footgun, personally.

You mean replace the footgun with a smaller one, maybe one so small it
doesn't matter. Saying that the proposal doesn't get rid of the footgun
means it still remains impossible to write x => {p: x} and not get what
Frankie and others want: an arrow returning an object. But the proposal
does fix that footgun.

How often do you really want an empty object instead of a block with no
statements?

/be
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: (x) => {foo: bar}

Frankie Bagnardi
That's good news, thanks for the strawman link.  Is it correct to assume this with that proposal?

var f = (x) => (y) => {x, y};
f(1)(2) // => {x: 1, y: 2};



On Mon, Jan 5, 2015 at 12:54 PM, Brendan Eich <[hidden email]> wrote:
Caitlin Potter wrote:
The strawman changes to the grammar are still ambiguous :(

`() => {}` -> noop or Object or SyntaxError? If SyntaxError, ...why?

No, the strawman addresses this: "An empty pair of braces |*{}*| other than at start of /Statement/ is an /ObjectLiteral/." The grammar is unambiguous. Notice the meta-? in the first production RHS below, and the non-empty-producing nature of the second:

Block:
    { UnlabeledStatementFirstList? }
    { WellLabeledStatement StatementList? }

UnlabeledStatementFirstList:
    UnlabeledStatement
    UnlabeledStatementFirstList Statement


The final piece of the puzzle is here:

We retain the |[lookahead ∉ {*{*, *function*}]| restriction in /ExpressionStatement/. At the start of a statement, |*{*| can be the start of a block only, never an object literal.

I think hacking around this would not get rid of the footgun, but would just make it more complicated to understand the footgun, personally.

You mean replace the footgun with a smaller one, maybe one so small it doesn't matter. Saying that the proposal doesn't get rid of the footgun means it still remains impossible to write x => {p: x} and not get what Frankie and others want: an arrow returning an object. But the proposal does fix that footgun.

How often do you really want an empty object instead of a block with no statements?

/be

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: (x) => {foo: bar}

Kevin Smith
In reply to this post by Caitlin Potter
I think hacking around this would not get rid of the footgun, but would just make it more complicated to understand the footgun, personally.

My gut reaction is to agree - the current rule, while it takes some trivial learning, is easy to understand and communicate and is reflected well in other parts of the language.  Also, additions to object literal syntax might make this more...weird:

   x => { [abc](def = function() { huh() }) { blahblahblah } };

"But it's an object literal, obviously!"


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: (x) => {foo: bar}

Brendan Eich-2
In reply to this post by Frankie Bagnardi
Frankie Bagnardi wrote:
> That's good news, thanks for the strawman link.  Is it correct to
> assume this with that proposal?
>
> var f = (x) => (y) => {x, y};
> f(1)(2) // => {x: 1, y: 2};

Good point, the strawman does not take object literal shorthand into
account and indeed parses {x, y} in an expression context as a block
expression, not an object literal. More work needed, it was only straw :-P.

To clarify something Caitlin raised: the goal is to enable block
expressions everywhere, and unify arrow function body on an expression
nonterminal, eiminating ConciseBody (in ES6) or the two production
right-parts in

ArrowFunctionExpression :
     ArrowFormalParameters =>  [lookahead ∉ { "{" }] AssignmentExpression
     ArrowFormalParameters =>  Block


from

http://wiki.ecmascript.org/doku.php?id=harmony:arrow_function_syntax

/be
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: (x) => {foo: bar}

Brendan Eich-2
In reply to this post by Kevin Smith
Kevin Smith wrote:

>
>     I think hacking around this would not get rid of the footgun, but
>     would just make it more complicated to understand the footgun,
>     personally.
>
>
> My gut reaction is to agree - the current rule, while it takes some
> trivial learning, is easy to understand and communicate and is
> reflected well in other parts of the language.  Also, additions to
> object literal syntax might make this more...weird:
>
>    x => { [abc](def = function() { huh() }) { blahblahblah } };
>
> "But it's an object literal, obviously!"

Yes, there's always a trade-off, some futures are foreclosed by syntax
changes of this sort.

Is it worth it? Hard to say, crystal ball service not answering the
phone ;-). Still, the motivation for that strawman I wrote in 2011 lives on.

/be
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: (x) => {foo: bar}

Caitlin Potter
In reply to this post by Brendan Eich-2
You mean replace the footgun with a smaller one, maybe one so small it doesn't matter. Saying that the proposal doesn't get rid of the footgun means it still remains impossible to write x => {p: x} and not get what Frankie and others want: an arrow returning an object. But the proposal does fix that footgun.
>
> How often do you really want an empty object instead of a block with no statements?

Okay, good point about the (lack of) ambiguity in terms of how it's interpreted, but what I'm talking about is how it looks like it should work. It looks like a function body and an object literal, and it doesn't matter which one is used more frequently, because it's going to bite people one way or the other. Rules about what sorts of statements are allowed as the first statement in a block is also going to bite people some times.

Because it bites fewer people, there will be fewer people who have dealt with it and are able to explain it, so it becomes one of those "gotchas" of the language.

This is my personal opinion, but I think the "wrap object literals in parentheses for concise bodies" is much simpler to explain to people than more complicated rules. Simple is good :>

On Mon, Jan 5, 2015 at 2:54 PM, Brendan Eich <[hidden email]> wrote:
Caitlin Potter wrote:
The strawman changes to the grammar are still ambiguous :(

`() => {}` -> noop or Object or SyntaxError? If SyntaxError, ...why?

No, the strawman addresses this: "An empty pair of braces |*{}*| other than at start of /Statement/ is an /ObjectLiteral/." The grammar is unambiguous. Notice the meta-? in the first production RHS below, and the non-empty-producing nature of the second:

Block:
    { UnlabeledStatementFirstList? }
    { WellLabeledStatement StatementList? }

UnlabeledStatementFirstList:
    UnlabeledStatement
    UnlabeledStatementFirstList Statement


The final piece of the puzzle is here:

We retain the |[lookahead ∉ {*{*, *function*}]| restriction in /ExpressionStatement/. At the start of a statement, |*{*| can be the start of a block only, never an object literal.

I think hacking around this would not get rid of the footgun, but would just make it more complicated to understand the footgun, personally.

You mean replace the footgun with a smaller one, maybe one so small it doesn't matter. Saying that the proposal doesn't get rid of the footgun means it still remains impossible to write x => {p: x} and not get what Frankie and others want: an arrow returning an object. But the proposal does fix that footgun.

How often do you really want an empty object instead of a block with no statements?

/be


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: (x) => {foo: bar}

Kevin Smith
In reply to this post by Brendan Eich-2
Also, I did some analysis on this issue way back when.  In the codebases that I looked at the percentage of "bound this functions" which simply returned an object literal were quite low.

(See the "%Object Literals" column)



Of course, actually having arrow functions will change the situation to some degree, but the current tradeoff made sense in light of that evidence.


On Mon, Jan 5, 2015 at 3:06 PM, Brendan Eich <[hidden email]> wrote:
Kevin Smith wrote:

    I think hacking around this would not get rid of the footgun, but
    would just make it more complicated to understand the footgun,
    personally.


My gut reaction is to agree - the current rule, while it takes some trivial learning, is easy to understand and communicate and is reflected well in other parts of the language.  Also, additions to object literal syntax might make this more...weird:

   x => { [abc](def = function() { huh() }) { blahblahblah } };

"But it's an object literal, obviously!"

Yes, there's always a trade-off, some futures are foreclosed by syntax changes of this sort.

Is it worth it? Hard to say, crystal ball service not answering the phone ;-). Still, the motivation for that strawman I wrote in 2011 lives on.

/be


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Fwd: (x) => {foo: bar}

Mark Volkmann
In reply to this post by Caitlin Potter
In addition, I don't think Traceur supports that syntax yet. I have had to do this instead:

let f = x => {
  return {foo: bar};
};

 __  __
/  \/  \
\      /ark
               Object Computing, Inc.
  \  /olkmann
   \/

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: (x) => {foo: bar}

Brendan Eich-2
In reply to this post by Brendan Eich-2
Brendan Eich wrote:

> Kevin Smith wrote:
>>
>>     I think hacking around this would not get rid of the footgun, but
>>     would just make it more complicated to understand the footgun,
>>     personally.
>>
>>
>> My gut reaction is to agree - the current rule, while it takes some
>> trivial learning, is easy to understand and communicate and is
>> reflected well in other parts of the language.  Also, additions to
>> object literal syntax might make this more...weird:
>>
>>    x => { [abc](def = function() { huh() }) { blahblahblah } };
>>
>> "But it's an object literal, obviously!"
>
> Yes, there's always a trade-off, some futures are foreclosed by syntax
> changes of this sort.

To say a bit more, your example *as written above* unambiguously shows
an object literal body, not a block expression body. It's complex, but
there's no valid parse that would interpret the stuff after => as a
block. But let's tweak it a bit:


    x => { [abc](def = function() { huh() })
           { blahblahblah } };


Now ASI applies and this parses as a block or an object literal. The
arrow body is ctually valid ES1!

The future-hostility of
http://wiki.ecmascript.org/doku.php?id=strawman:block_vs_object_literal 
must be traded off against the complexity burden of every-more elaborate
object literal extension syntax. At some point we can stop extending
object literals. Are we there yet?

If so, then the {x, y} shorthand problem Frankie raised remains. One
brute-force way out is to ban leading comma expression statements in
UnlabeledStatement: ExpressionStatement, which could be done. I'm still
thinking about this, not super-worried.

Given ES6 arrows as drafted and implemented, and as about to be
finalized, the main problem that I foresee with adding
block_vs_object_literal in ES7 is how () = {} makes an empty-block body.
That's why I asked

"How often do you really want an empty object instead of a block with no
statements?"

a few messages back. Serious question!

/be
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: (x) => {foo: bar}

Marius Gundersen
In reply to this post by Kevin Smith

One scenario where arrow functions are likely to return objects is in the map function of arrays and the pipe function for streams. For example:

[1,2,3]
.map(x => {value: x,  double:2*x})
.filter(x => x.double < 5)

Marius Gundersen

On 5 Jan 2015 21:16, "Kevin Smith" <[hidden email]> wrote:
>
> Also, I did some analysis on this issue way back when.  In the codebases that I looked at the percentage of "bound this functions" which simply returned an object literal were quite low.
>
> (See the "%Object Literals" column)
>
> https://docs.google.com/spreadsheet/ccc?key=0Aro5yQ2fa01xdENxUzBuNXczb21vUWVUX0tyVmNKTUE#gid=0
> https://docs.google.com/spreadsheet/ccc?key=0Aro5yQ2fa01xdEJySWxhZ1VoZ0VaWTdldXp4NUtJd3c#gid=0
>
> (from https://esdiscuss.org/topic/btf-measurements)
>
> Of course, actually having arrow functions will change the situation to some degree, but the current tradeoff made sense in light of that evidence.
>
>
> On Mon, Jan 5, 2015 at 3:06 PM, Brendan Eich <[hidden email]> wrote:
>>
>> Kevin Smith wrote:
>>>
>>>
>>>     I think hacking around this would not get rid of the footgun, but
>>>     would just make it more complicated to understand the footgun,
>>>     personally.
>>>
>>>
>>> My gut reaction is to agree - the current rule, while it takes some trivial learning, is easy to understand and communicate and is reflected well in other parts of the language.  Also, additions to object literal syntax might make this more...weird:
>>>
>>>    x => { [abc](def = function() { huh() }) { blahblahblah } };
>>>
>>> "But it's an object literal, obviously!"
>>
>>
>> Yes, there's always a trade-off, some futures are foreclosed by syntax changes of this sort.
>>
>> Is it worth it? Hard to say, crystal ball service not answering the phone ;-). Still, the motivation for that strawman I wrote in 2011 lives on.
>>
>> /be
>
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
>


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: (x) => {foo: bar}

Brendan Eich-2
In reply to this post by Caitlin Potter
Caitlin Potter wrote:

> > You mean replace the footgun with a smaller one, maybe one so small
> it doesn't matter. Saying that the proposal doesn't get rid of the
> footgun means it still remains impossible to write x => {p: x} and not
> get what Frankie and others want: an arrow returning an object. But
> the proposal does fix that footgun.
> >
> > How often do you really want an empty object instead of a block with
> no statements?
>
> Okay, good point about the (lack of) ambiguity in terms of how
> it's interpreted, but what I'm talking about is how it looks like it
> should work. It looks like a function body and an object literal, and
> it doesn't matter which one is used more frequently, because it's
> going to bite people one way or the other.

True. Can't share { as I did in JS and avoid this. Ship sailed long ago.

> Rules about what sorts of statements are allowed as the first
> statement in a block is also going to bite people some times.

Probably not useless labels at the front. Seriously, the change to allow
labels only at top level or else in front of any label-using statement
(and no other) is almost perfectly backward compatible. Stray and unused
labels are latent bugs, even if just minor left-over or misplace noise.

> Because it bites fewer people, there will be fewer people who have
> dealt with it and are able to explain it, so it becomes one of those
> "gotchas" of the language.

Yes, a smaller footgun -- not the same one that started this thread. I
agree it's vexing to have a footgun left, but if it differs in quality
and frequency of misfires, maybe it's worthwhile. Hard to assess.

I also agree KISS favors what we all agreed to do, which was (a) take
arrows into ES6; (b) not pursue block_vs_object_literal after I wrote it
up. But we could revisit (b) and that seems worth some es-discuss overhead.

> This is my personal opinion, but I think the "wrap object literals in
> parentheses for concise bodies" is much simpler to explain to people
> than more complicated rules. Simple is good :>

Your advice is good as far as it goes; it seems not to reach enough
people to avoid a real-world speedbump, from the root message in this
thread.

If the speedbump were caught at compile-time, no big. That it results in
runtime behavior differing from the DWIM intent of the programmer means
latent bugs. Perhaps JSLint, ESHint, etc., will be updated to catch the
bad thing in the field, and that will suffice.

/be
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: (x) => {foo: bar}

Mark Volkmann
In reply to this post by Mark Volkmann
My apologies. I meant to say that Traceur doesn't support returning a literal object from an arrow function with syntax like this:

let f = x => ({foo: bar});

However, I just tested it again and it works fine. I could swear this didn't work a few months ago. Maybe it was fixed recently. I'm happy!

On Mon, Jan 5, 2015 at 2:48 PM, Mark Volkmann <[hidden email]> wrote:
In addition, I don't think Traceur supports that syntax yet. I have had to do this instead:

let f = x => {
  return {foo: bar};
};

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: (x) => {foo: bar}

Brendan Eich-2
Mark Volkmann wrote:
> My apologies. I meant to say that Traceur doesn't support returning a
> literal object from an arrow function with syntax like this:
>
> let f = x => ({foo: bar});
>
> However, I just tested it again and it works fine. I could swear this
> didn't work a few months ago. Maybe it was fixed recently. I'm happy!

Cool -- you are supporting Caitlin's thesis that we can pedagogue around
the footgun. I hope so.

Still leaves
http://wiki.ecmascript.org/doku.php?id=strawman:block_vs_object_literal 
as an option for ES7. Comments welcome.

/be
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
123