Named Arrow Declaration

I've found myself using this invalid syntax in my notes:

const mix( a, b, t ) => ( t-a.t )*b.x + ( b.t-t )*a.x;

It abbreviates the assignment.

const mix = ( a, b, t ) => ...

This abbreviation does not suffer from the same ambiguity as omiting the function keyword. Is there a chance it could someday be valid?

2 Likes

It's an interesting idea. But proposals like this often have a hard time getting through. They add a little more complexity to the language, and another thing to learn, and the only benefit is removing an "=" from your source code.

Though, every once in a while a shorthand syntax goes through (we use { x, y } instead of { x: x, y: y }, and arrow functions themselves are mostly meant to be a shorthand for function() { return ... }, etc)

1 Like

So, "every once in a while" might mean maybe?

I can't imagine a proposal devoted to this one tiny change.
I wonder if there exists a proposal that could include this.

Could also add shorthand property declaration for arrow functions.
When learning the language, I would naturally expect this to work:

const a = { m(x) => x+1 }

Given that this works:

const a = { m(x) { return x+1 } }

New syntax is an incredibly massive change that would absolutely require a proposal.

Some proposals only contain minor changes (e.g. this proposal defines a single function that anyone could define with one line of code) - there's nothing wrong with having things like this be in their own proposal.

Maybe ... I personally would be against it. I don't think the slight added language complexity is worth the slight abbreviation. I guess I don't find that syntax intuitive enough. But others would probably disagree with me.

2 Likes

In your opinion, is this worth pursuing?

I'd use it - rather than relying on function name inference, and in places like export default or function arguments where an arrow function can't otherwise get a name - but I don't think it's worth the syntax churn just to avoid using a normal named function.

Hmmm.

Well, I'll leave it at: I hope some proposal eventually includes this for a more justifiable reason.

Hi there, sorry for intruding in this discussion which hasn't been active for a while.

I just stumbled across this thread as I was actually thinking of opening one like this myself

I just wanted to mention another couple of reasons why this could in my opinion be quite a nice addition

Firstly, I would just like to say that for via function we can actually define both named and anonymous functions, so it would actually stand to reason to me that the same should be possible with arrow functions as well (without the need to rely on name inference as @ljharb mentioned).

Second (which sort of adds to what @ljharb mentioned), I think that it would be very good for callbacks, those are currently always anonymous (unless you go out of your was and use function instead) and they usually create various anonymous calls in the call stack which aren't as easily debuggable.

As a very simple example, let's say I have

myArray.forEach(el => { return el+1; });

inside the callback function the call stack would just say that the function is anonymous, and to actually have that function named we'd have to do:

myArray.forEach(function addOne(el){ return el+1; })

(or have define the addOne arrow function in a previous statement)
it would be quite neat if we could instead do:

myArray.forEach(addOne(el) => { return el+1; });

Of course this is an extremely simple example but with frameworks/libraries which highly depend on callbacks (I am for example thinking of rxjs) it could actually quite improve the developer experience (and defining the arrow functions prior to the callback just so that they can name-inferred could just create clutter)

Anyways I just wanted to mention that :slightly_smiling_face:

1 Like

Nit: async arrow functions conflict with that.

good point! :sweat:

It would be so nice!

For debugging purposes this is the best workaround I've got:

const DEBUG = { ... }

myArray.forEach( DEBUG.addOne = el => { return el+1; } );

If that function throws (e.g. if the array contains a BigInt), Firefox will now trace that function as addOne, and Chrome will trace it as myArray.forEach.DEBUG.addOne.

That seems like it's a lot more difficult than myArray.forEach(function (el) { return el + 1; }).

In Firefox, the error origin for that code was simply <anonymous>, same non-traceable problem as the anonymous arrow function. But if I add a name, it is hoisted / pollutes the scope.

function expression names aren't added to the containing scope. That only happens for declarations (when the function is not being used as an expression).

myArray.forEach(function myFunc(el) { return el + 1; })
console.log(myFunc) // Error: not defined
2 Likes

Indeed they are not. :expressionless:

I really did test it in the console before I posted that (essentially the same code you posted), and the function was defined. My console scope must have been dirty from some earlier line. (This thread has also wandered off-topic at this point.)

I personally think that it is worth allowing this syntax in a class because class { m = x => x + 1 } does behave differently from class { m(x) { return x + 1 } }: only the latter puts the method into the prototype. Sometimes I find myself really wanting to inline a class method.