Functions as blocks

# Brian Terlson (5 years ago)

We have discussed, at length, the various ways in which browsers differ in their handling of functions-in-blocks:


if(test) {

    function foo() { }

}

At the last TC-39 we approved semantics for block-scoped functions in sloppy mode. We did not discuss directly, that I recall, how the following should be handled:


if(test) function foo() { }

Per spec I believe this is a syntax error, but all browsers seem to allow it (with minor differences in semantics similar to function-in-block scenarios).

Are implementers going to be making this an error or carrying forward this extension? If carrying forward, are there any objections to adding this extension to Annex B with minimal intersection semantics similar to F-I-B?

I haven't collected much data on this so I'm not sure what the prevalence is, but we'd err on the side of caution and continue supporting it unless other implementers are confident enough to remove it. If no one will be removing it, it makes sense to me to add this to Annex B. Eager to hear what others' thoughts are.

# Brendan Eich (5 years ago)

Brian Terlson wrote:

I haven't collected much data on this so I'm not sure what the prevalence is,

Can you try to find some sightings in the wild?

# Brian Terlson (5 years ago)

I have searched my Alexa Top 10k dataset and didn't find any occurrences. The dataset has the same limitations as before - only front page load, no dynamic scripts - with the added problem of now being ~1.5yrs old. I'm not sure how much the absence of this pattern tells us.

My thinking is that instrumenting some runtime and browsing/crawling the web would give us the data to feel confident about dropping this "feature". Unfortunately that isn't an option available to me to try at the moment... Open to other suggestions, though!

# John Barton (5 years ago)

On Wed, Mar 5, 2014 at 3:08 PM, Brian Terlson <Brian.Terlson at microsoft.com>wrote:

I have searched my Alexa Top 10k dataset and didn't find any occurrences. The dataset has the same limitations as before - only front page load, no dynamic scripts - with the added problem of now being ~1.5yrs old. I'm not sure how much the absence of this pattern tells us.

The biggest problem with this test is that the Alexa set selects for sites with experienced developers writing for production sites. The pattern you are trying to detect is not used in these circumstances.

My thinking is that instrumenting some runtime and browsing/crawling the web would give us the data to feel confident about dropping this "feature". Unfortunately that isn't an option available to me to try at the moment... Open to other suggestions, though!

As you say "all browsers seem to allow it". Browsers made the mistake and we should not go back now and blame developers on smaller sites because they use this kind of code. Make it a syntax error in modules and save yourself a lot of headaches.

# Brendan Eich (5 years ago)

John Barton wrote:

As you say "all browsers seem to allow it". Browsers made the mistake and we should not go back now and blame developers on smaller sites because they use this kind of code. Make it a syntax error in modules and save yourself a lot of headaches.

We could do this for sure, and in the absence of evidence that if (x) function y(){} is used in the wild, we should. With such evidence, we should. So, we should ;-).

But there's more to consider. IIRC, originally KJS (pre-JSC) in WebKit did not support function-in-block or function-in-unbraced-consequent. Then they added function-in-block support, bowing to the well-known uses on the Web. When did they add function-in-unbraced, and why? Perhaps someone can cite the fixed webkit.org bug.

# Allen Wirfs-Brock (5 years ago)

We would have to come up with an an appropriate intersection semantics and we don't have a base ES semantics to work off of as a function declaration is illegal in that posiion in ES6. Would we also have to accommodate it for IterationStatements and WithStatement

# Brendan Eich (5 years ago)

On Mar 5, 2014, at 6:53 PM, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:

We would have to come up with an an appropriate intersection semantics and we don't have a base ES semantics to work off of as a function declaration is illegal in that posiion in ES6. Would we also have to accommodate it for IterationStatements and WithStatement

Right, it is not free - nothing around here is!

The other way to go optimizes for the reason WebKit folks added unbraced support no longer applying: leave draft ES6 as is, implement and test among major browsers, and see what comes out in the wash.

If no one else looks, I will try to find the WebKit.org bug trail.

# Boris Zbarsky (5 years ago)

On 3/5/14 4:26 PM, Brian Terlson wrote:

I haven't collected much data on this so I'm not sure what the prevalence is

Given the number of stackoverflow posts I've seen that come down to browsers not being exactly compatible on their handling of this code, its prevalence is too high to allow us to remove the behavior in simple cases. :(

# Brian Terlson (5 years ago)

John Barton wrote:

The biggest problem with this test is that the Alexa set selects for sites with experienced developers writing for production sites. The pattern you are trying to detect is not used in these circumstances.

I agree that this dataset is not representative of all JS code. Although, to provide some context, the same set contains nearly 2000 sites that declare functions in blocks (~60 of those declare those functions in loops).

John Barton wrote:

As you say "all browsers seem to allow it". Browsers made the mistake and we should not go back now and blame developers on smaller sites because they use this kind of code.

Boris Zbarsky wrote:

Given the number of stackoverflow posts I've seen that come down to browsers not being exactly compatible on their handling of this code, its prevalence is too high to allow us to remove the behavior in simple cases. :(

Chakra, and other implementations I imagine, will remove features that are non-standard and are unused. Getting usage data is the hard part, so anything concrete anyone can share would be helpful. I am in favor of removing this if we can convince ourselves it won't break people, but I agree that without good data the conservative approach is better.

Brendan Eich wrote:

If no one else looks, I will try to find the WebKit.org bug trail.

I tried searching, and failed. Let me know if you have better luck!

# Allen Wirfs-Brock (5 years ago)

On Mar 6, 2014, at 10:07 AM, Brian Terlson wrote:

Chakra, and other implementations I imagine, will remove features that are non-standard and are unused. Getting usage data is the hard part, so anything concrete anyone can share would be helpful. I am in favor of removing this if we can convince ourselves it won't break people, but I agree that without good data the conservative approach is better.

I'm talking to an academic contact of mine who has a corpus of about a million unique JS files recently spidered off the web. Hopefully, they can look for this usage pattern....