Shorter syntax for arrow function assignment
-1 this fails styleguide sanity-check.
we currently have 3 common styles of declaring functions:
- foo = function () {...}
- function foo () {...}
- foo = () => {...}
does this extra 4th style offer anything new to justify making the javascript language even less consistent than it already is? i say no.
This syntax is shorter, easier to write, and arguably easier to read. What else does it need to offer?
It can be confusing because it is too similar to non-arrow functions. The arrow syntax is clear in meaning.
It needs to offer more than two characters, and no confusing confliction with shorthand method syntax.
As arrow function const assignments become the norm and non-arrows the exception, allowing syntactical cruft to fall away makes sense to me. It might be premature based on overall 2015 adoption, but I don't see this trend reversing.
to me this export foo() {}
makes sense only as shortcut for export function foo() {}
and not as arrow, because arrow missing context and
arguments will mislead everyone exporting a named function.
+1 for omitting function keyword between export and function name.
Declaring arrow functions without arrow in syntax - nope, nope, nope.
I certainly understand the "misleading" perspective, but also consider ES5- function syntax to be deteriorating such that this shorthand would be wasted on it.
Agree with Andrea on this one. Method syntax (in an object initializer, in
a class
) creates a method (a non-arrow function with a [[HomeObject]]
slot), not an arrow function. This looks just like method syntax. The
absence of the arrow is too misleading.
I could see it as a shortcut for export function foo() { }
, but not for
export const foo = () => { };
.
-- T.J. Crowder
ICYMI: my stance is that ES5- functions are already outmoded - and are rapidly becoming the lesser-used option - so it would be a waste of a syntax win.
My major concern is this can be confusing with the "this" binding. The object wrapping being the only difference between:
// Existing:
const x = {
myFn() { }
};
// Proposed, with different meaning:
const myFn() { } // Why would "this" bind to myFn?
Omitting the arrow is a major -1 for me -- the whole point of "=>" is that
it does not provide a "this" to the scope of the function body.
Also, you cannot implicitly omit the "const", as these are all valid:
export var symbol = ...
export let symbol = ...
export const symbol = ...
Also, you cannot implicitly omit the "const"
Paving a cowpath, const has won named function assignment.
Another annoying thing JS has to deal with is:
// implicitly 'var'
someVar = 10;
So, something like:
myFn() {
}
Would be considered as:
var myFn = function() {
}
with what semantics exist now. Not best practices, but what is currently interpreted in the language.
I'd 100% agree that, as a shorthand, this is nice:
myFn() { }
const myFn = () => {}
Which is what I mean. But I'm not the full implementation of JavaScript.
At current, sans an explicit assignment, the pragma foo() {...}
should
throw.
functions are already outmoded
I don't know where you come from but to me:
// this ain't outmoded at all
const obj = {
method() { return this === obj; }
};
// this ain't outmoded at all
class Any {
method() { return this instanceof Any; }
}
And a module that provides mixins is definitively not outmoded at all
export method() {
return this !== undefined;
};
Omitting the arrow is everything but a syntax win here.
There is practically no gain to suggest this syntax for arrows anyway as a module has no this binding you are creating a perpetually contextless function whereas using this shorthand syntax for a normal function makes some sense. You lose implicit return regardless.
- Matthew Robb
"ES5 functions" - by which you mean, normal functions - are not
"outmoded", they remain necessary for any use case where this
needs to be
determined at invocation time.
Nothing should ever produce an arrow function without =>
; and exports
assuming const
is an interesting idea, but explicit > implicit, and
"typing less" is simply not a goal worth optimizing for by itself.
normal functions ... remain necessary for any use case where
this
needs
to be determined at invocation time.
On its way to being an edge case.
This is the case that is fading away (and probably isn't coming back into vogue ever again):
const Foo = function() {
this.bar = `b4r`;
};
The use case fading away doesn't mean you can drop support for it, or that it won't still be in use.
Please stop trying to push your "shorthand" syntax of:
myFn() {
}
It's already been pointed out in multiple cases that:
- The current usages are not "outmoded"
- The proposed syntax has misleading
this
binding without the arrow - Blocks, ASI, and the object shorthand notation either conflict or make it vague how to interpret
This isn't a beneficial syntax moving forward, and it doesn't seem to add anything other than "I don't like typing '='".
To be clear, this isn't a proposal to drop support for something. Don't optimize for a fading use-case, however.
it doesn't seem to add anything other than "I don't like typing '='".
That is absolutely correct, it is a proposal for shorthand syntax.
It doesn't matter if function
s are being used less, they simply
aren't going away. There's plenty of people specifically relying on
function
for certain purposes where arrow functions do not work.
Lets avoid getting arrows confused with functions.
const prototype = /* ... get this prototype object from somewhere ... */
prototype.foo = function foo() {
// do something with `this`.
}
That sort of stuff (relying on non-arrows) isn't going away. /#!/JoePea
On its way to being an edge case.
Not really because arrow functions are not re-bindable. They are always bound to a single object since their creation. They are meant to be used as “lambda” functions”, while providing a workaround for accessing properties of their “parent object” (ie the object referred by “this” at their creation). They are not simply a shortcut version of “function” like many people thinks.
From: Brian Blakely [mailto:anewpage.media at gmail.com] Sent: Tuesday, October 24, 2017 3:39 PM To: Jordan Harband <ljharb at gmail.com>
Cc: dante federici <c.dante.federici at gmail.com>; es-discuss <es-discuss at mozilla.org>
Subject: Re: Re: Shorter syntax for arrow function assignment
normal functions ... remain necessary for any use case where
this
needs to be determined at invocation time.
On its way to being an edge case.
On Tue, Oct 24, 2017 at 2:46 PM, Jordan Harband <ljharb at gmail.com <mailto:ljharb at gmail.com> > wrote:
"ES5 functions" - by which you mean, normal functions - are not "outmoded", they remain necessary for any use case where this
needs to be determined at invocation time.
Nothing should ever produce an arrow function without =>
; and exports assuming const
is an interesting idea, but explicit > implicit, and "typing less" is simply not a goal worth optimizing for by itself.
On Tue, Oct 24, 2017 at 11:05 AM, Matthew Robb <matthewwrobb at gmail.com <mailto:matthewwrobb at gmail.com> > wrote:
There is practically no gain to suggest this syntax for arrows anyway as a module has no this binding you are creating a perpetually contextless function whereas using this shorthand syntax for a normal function makes some sense. You lose implicit return regardless.
- Matthew Robb
On Tue, Oct 24, 2017 at 1:47 PM, Andrea Giammarchi <andrea.giammarchi at gmail.com <mailto:andrea.giammarchi at gmail.com> > wrote:
functions are already outmoded
I don't know where you come from but to me:
// this ain't outmoded at all
const obj = {
method() { return this === obj; }
};
// this ain't outmoded at all
class Any {
method() { return this instanceof Any; }
}
And a module that provides mixins is definitively not outmoded at all
export method() {
return this !== undefined;
};
Omitting the arrow is everything but a syntax win here.
On Tue, Oct 24, 2017 at 2:32 PM, Brian Blakely <anewpage.media at gmail.com <mailto:anewpage.media at gmail.com> > wrote:
At current, sans an explicit assignment, the pragma foo() {...}
should throw.
On Tue, Oct 24, 2017 at 1:26 PM, dante federici <c.dante.federici at gmail.com <mailto:c.dante.federici at gmail.com> > wrote:
Another annoying thing JS has to deal with is:
// implicitly 'var'
someVar = 10;
So, something like:
myFn() {
}
Would be considered as:
var myFn = function() {
}
with what semantics exist now. Not best practices, but what is currently interpreted in the language.
I'd 100% agree that, as a shorthand, this is nice:
myFn() { }
const myFn = () => {}
Which is what I mean. But I'm not the full implementation of JavaScript.
I 100% agree it's a terrible idea, and this proposal's syntax sucks for this very reason.
I'll note a few things:
- The main proposal AFAICT is for
let foo() {}
, notfoo() {}
. - It does not syntactically conflict with object methods, because it's only valid as a statement.
- It conflicts with existing ASI, but only with
let
andvar
, where this is currently unambiguously valid (it's open real estate withconst
):
let
foo
(
x
)
{
}
// Parsed in both sloppy and strict as:
let foo;
(x);
{}
On Tue, Oct 24, 2017 at 6:26 PM, dante federici <c.dante.federici at gmail.com> wrote:
So, something like:
myFn() { }
Would be considered as:
var myFn = function() { }
with what semantics exist now. Not best practices, but what is currently interpreted in the language.
No, it isn't. It's a SyntaxError: Unexpected token {
. There's a big
difference between myFn() { }
and myFn = function() { };
The latter is
valid syntax for the horror of implicit globals (in loose mode; strict mode
fixed it). The former is just a syntax error. (It would be valid method
syntax if it were inside an object initializer or class
.)
But AFAIK, Brian Blakely wasn't promoting that syntax anyway. His original
post only ever uses this shorthand with export
, so I think it was meant
to be specific to exporting.
-- T.J. Crowder
On Wed, Oct 25, 2017 at 4:57 AM, T.J. Crowder < tj.crowder at farsightsoftware.com> wrote:
On Tue, Oct 24, 2017 at 6:26 PM, dante federici <c.dante.federici at gmail.com> wrote:
So, something like:
myFn() { }
Would be considered as:
var myFn = function() { }
with what semantics exist now. Not best practices, but what is currently interpreted in the language.
No, it isn't. It's a
SyntaxError: Unexpected token {
. There's a big difference betweenmyFn() { }
andmyFn = function() { };
The latter is valid syntax for the horror of implicit globals (in loose mode; strict mode fixed it). The former is just a syntax error. (It would be valid method syntax if it were inside an object initializer orclass
.)
ya this is not a syntax error. myFn() { }
On Wed, Oct 25, 2017 at 3:11 PM, J Decker <d3ck0r at gmail.com> wrote:
ya this is not a syntax error.
myFn() { }
Indeed it isn't, but that isn't what I referred to in dante's message, nor is it what he was suggesting it would be. He quoted
myFn() {
}
...which is indeed a syntax error because ASI doesn't kick in. This:
myFn()
{
}
...isn't a syntax error because ASI adds a ;
after myFn()
, making
it a function call followed by a standalone block, not the function
declaration/expression he suggested it was.
All of which is by-the-bye, though, as I don't think Brian was suggesting that anyway... :-)
-- T.J. Crowder
Sorry I was unclear -- I was referring to "If we were to add this syntax, then seeing this code with knowing how JS interprets the current syntax, I would expect [x] to be the outcome"
I wasn't trying to imply it would work as-is -- either way, sorry for not being clear. If anything the confusion around the newline interacting with the shortened syntax as well as this miscommunication should probably indicate something about the idea.
A prevalent pattern has emerged:
export const foo = ()=> { };
Taking a cue from short method syntax, this comes to mind as a possible improvement:
export const foo() { };
Even better if we assume const:
export foo() { };
That is delicious. Thoughts?