Function declaration in labelled statements

# Shijun He (12 years ago)

ES5 strict mode disallow Function declaration in any statements. It's fine, but Function declaration in top labelled statements seems harmless, why not relax the rules to allow them so we can use "Labeled Modules Specification" ? Though it seems too late to fix.

Code example:

'use strict' // cause SyntaxError: In strict mode code, functions can only be declared at top level or immediately within another function.

exports: function area(x1, y1, x2, y2){ return length(x1, x2) * length(y1, y2); }

References: Labeled Modules Specification: labeledmodules/labeled-modules-spec LMS implementation: npmjs.org/package/linkjs my.js (ES6-like module system which utilize the same ideas from LMS for import/export syntax): hax/my.js

-- hax

# Brendan Eich (12 years ago)

Shijun He wrote:

ES5 strict mode disallow Function declaration in any statements. It's fine, but Function declaration in top labelled statements seems harmless, why not relax the rules to allow them so we can use "Labeled Modules Specification" ? Though it seems too late to fix.

It is, see below.

Code example:

'use strict' // cause SyntaxError: In strict mode code, functions can only be declared at top level or immediately within another function.

exports: function area(x1, y1, x2, y2){ return length(x1, x2) * length(y1, y2); }

This is a labeled named function expression statement, given a ; or ASI after the closing brace. We can't change its meaning to declare a function area, with hoisted name. That's an incompatible change, and while it might seem unlikely to break any real code, you would be surprised.

People tend to make unnecessary labels, especially in event handlers where javascript: at the front of the HTML attribute value has been seen in the wild. Couple that with a function expression that is not parenthesized, but possibly immediately invoked, and you have real trouble.

The grammatical problem is harder: we use lookahead restriction,

ExpressionStatement : [lookahead ∉ {{, function}] Expression ;

to prevent a function expression from starting an expression statement. To allow a labeled function declaration (not expression) we would have to make this lookahead restriction conditional on whether the ExpressionStatement is labeled.

Crock and I have proposed restricting labeled statements to those that could use the label (not expression statements, currently; but block lambdas could make this future-hostile, although we have nearly unanimously ruled out Tennent's Correspondence Principle designs in the future that want such a label-using block-lambda). See

strawman:block_vs_object_literal

This looks like more trouble than it is worth, and again, it's an incompatible change. Those rogue javascript: labels exist on the web.