Function declarations as statements

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

Function declarations as statements

Michael Day
Hi,

In ECMAScript, function declarations are SourceElements, but not
Statements. This means that they can only occur at the top level, and
may not be nested inside a block.

However, browsers support function declarations as statements, and many
scripts on the web seem to make use of this ability, especially after
they have been minified.

Is there a spec anywhere for how functions as statements should behave?

Can they be rewritten to var + function expression, so that this:

{
     function f() { return 17 }
}

becomes this:

{
     var f = function() { return 17 }
}

When implementing non-standard features, it would be nice to do so in a
standard manner :)

Best regards,

Michael

--
Print XML with Prince!
http://www.princexml.com
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Function declarations as statements

Brendan Eich-3
A recurring topic. See:

https://mail.mozilla.org/pipermail/es-discuss/2007-March/003964.html
https://mail.mozilla.org/pipermail/es-discuss/2008-February/005314.html
https://mail.mozilla.org/pipermail/es-discuss/2008-July/006812.html

and probably many others.

There's no common semantics among top five browsers (although IIRC three follow IE, the #2 by market share did something different long, long ago).

So for Harmony, we are reclaiming function in block (must be a direct child of a braced block) to bind a block-local name on block entry (so hoisting lives, but only to top of block -- so you can't emulate with var f = function ...).

/be

On Nov 11, 2010, at 3:46 PM, Michael Day wrote:

> Hi,
>
> In ECMAScript, function declarations are SourceElements, but not Statements. This means that they can only occur at the top level, and may not be nested inside a block.
>
> However, browsers support function declarations as statements, and many scripts on the web seem to make use of this ability, especially after they have been minified.
>
> Is there a spec anywhere for how functions as statements should behave?
>
> Can they be rewritten to var + function expression, so that this:
>
> {
>    function f() { return 17 }
> }
>
> becomes this:
>
> {
>    var f = function() { return 17 }
> }
>
> When implementing non-standard features, it would be nice to do so in a standard manner :)
>
> Best regards,
>
> Michael
>
> --
> Print XML with Prince!
> http://www.princexml.com
> _______________________________________________
> 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: Function declarations as statements

Allen Wirfs-Brock-2
In reply to this post by Michael Day
From the ES5 spec section 12 statement semantics:

NOTE Several widely used implementations of ECMAScript are known to support the use of FunctionDeclaration as a Statement. However there are significant and irreconcilable variations among the implementations in the semantics applied to such FunctionDeclarations. Because of these irreconcilable differences , the use of a FunctionDeclaration as a Statement results in code that is not reliably portable among implementations. It is recommended that ECMAScript implementations either disallow this usage of FunctionDeclaration or issue a warning when such a usage is encountered. Future editions of ECMAScript may define alternative portable means for declaring functions in a Statement context.

Also see section on functions in http://blogs.msdn.com/b/ie/archive/2010/08/25/chakra-interoperability-means-more-than-just-standards.aspx 

There seem to be more browsers that treat function declarations in blocks as straightforward extensions of the function hoisting semantics (unconditionally) but Firefox does something different.

As I say in the above blog post, you have to have them in a browser but anything other than trivial usage is unlike to be interoperable.

Allen
 

> -----Original Message-----
> From: [hidden email] [mailto:es-discuss-
> [hidden email]] On Behalf Of Michael Day
> Sent: Thursday, November 11, 2010 3:46 PM
> To: ES-Discuss
> Subject: Function declarations as statements
>
> Hi,
>
> In ECMAScript, function declarations are SourceElements, but not Statements.
> This means that they can only occur at the top level, and may not be nested
> inside a block.
>
> However, browsers support function declarations as statements, and many
> scripts on the web seem to make use of this ability, especially after they have
> been minified.
>
> Is there a spec anywhere for how functions as statements should behave?
>
> Can they be rewritten to var + function expression, so that this:
>
> {
>      function f() { return 17 }
> }
>
> becomes this:
>
> {
>      var f = function() { return 17 }
> }
>
> When implementing non-standard features, it would be nice to do so in a
> standard manner :)
>
> Best regards,
>
> Michael
>
> --
> Print XML with Prince!
> http://www.princexml.com
> _______________________________________________
> 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: Function declarations as statements

Michael Day
In reply to this post by Brendan Eich-3
Hi Brendan and Allen,

Thanks for the pointers.

> So for Harmony, we are reclaiming function in block (must be a direct child of a braced block) to bind a block-local name on block entry (so hoisting lives, but only to top of block -- so you can't emulate with var f = function ...).

If we implemented this behaviour now, I think that would be sufficient
to make JQuery and Raphaël work. Here is an example from JQuery that is
giving us trouble:

if (condition) {
     var val, props, ... ;

     function getWH() { ... this is the function ... }

     if ( elem.offsetWidth !== 0 ) {
         getWH();
     } else {
         jQuery.swap( elem, props, getWH );
     }

     return Math.max(0, Math.round(val));
}

The getWH() function is declared in the block and only used in the
block, so if we hoisted the definition to the top of the block there
would not be any problems with this usage.

Best regards,

Michael

--
Print XML with Prince!
http://www.princexml.com
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

RE: Function declarations as statements

Allen Wirfs-Brock-2
I believe that would be interoperable as long as each such function is only declared and used within a single block.  Multiple declarations with the same function name in separate blocks wouldn't be interoperable among all browsers.

Allen

> -----Original Message-----
> From: Michael Day [mailto:[hidden email]]
> Sent: Thursday, November 11, 2010 4:48 PM
> To: Brendan Eich
> Cc: ES-Discuss; Allen Wirfs-Brock
> Subject: Re: Function declarations as statements
>
> Hi Brendan and Allen,
>
> Thanks for the pointers.
>
> > So for Harmony, we are reclaiming function in block (must be a direct child of
> a braced block) to bind a block-local name on block entry (so hoisting lives, but
> only to top of block -- so you can't emulate with var f = function ...).
>
> If we implemented this behaviour now, I think that would be sufficient to make
> JQuery and Raphaël work. Here is an example from JQuery that is giving us
> trouble:
>
> if (condition) {
>      var val, props, ... ;
>
>      function getWH() { ... this is the function ... }
>
>      if ( elem.offsetWidth !== 0 ) {
>          getWH();
>      } else {
>          jQuery.swap( elem, props, getWH );
>      }
>
>      return Math.max(0, Math.round(val)); }
>
> The getWH() function is declared in the block and only used in the block, so if we
> hoisted the definition to the top of the block there would not be any problems
> with this usage.
>
> Best regards,
>
> Michael
>
> --
> Print XML with Prince!
> http://www.princexml.com

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

Re: Function declarations as statements

Mark S. Miller-2
On Thu, Nov 11, 2010 at 5:10 PM, Allen Wirfs-Brock <[hidden email]> wrote:
I believe that would be interoperable as long as each such function is only declared and used within a single block.  Multiple declarations with the same function name in separate blocks wouldn't be interoperable among all browsers.

Not quite. It will be incompatible with ES5/strict on those ES5 implementations that follow <http://wiki.ecmascript.org/doku.php?id=conventions:no_non_standard_strict_decls>.

For the example code you show under the assumptions you state, if you move the function declaration into the top level of the containing function or program, then it will be compat with ES5/strict best practice as well, and still with everything else.

 

Allen

> -----Original Message-----
> From: Michael Day [mailto:[hidden email]]
> Sent: Thursday, November 11, 2010 4:48 PM
> To: Brendan Eich
> Cc: ES-Discuss; Allen Wirfs-Brock
> Subject: Re: Function declarations as statements
>
> Hi Brendan and Allen,
>
> Thanks for the pointers.
>
> > So for Harmony, we are reclaiming function in block (must be a direct child of
> a braced block) to bind a block-local name on block entry (so hoisting lives, but
> only to top of block -- so you can't emulate with var f = function ...).
>
> If we implemented this behaviour now, I think that would be sufficient to make
> JQuery and Raphaël work. Here is an example from JQuery that is giving us
> trouble:
>
> if (condition) {
>      var val, props, ... ;
>
>      function getWH() { ... this is the function ... }
>
>      if ( elem.offsetWidth !== 0 ) {
>          getWH();
>      } else {
>          jQuery.swap( elem, props, getWH );
>      }
>
>      return Math.max(0, Math.round(val)); }
>
> The getWH() function is declared in the block and only used in the block, so if we
> hoisted the definition to the top of the block there would not be any problems
> with this usage.
>
> Best regards,
>
> Michael
>
> --
> Print XML with Prince!
> http://www.princexml.com

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



--
    Cheers,
    --MarkM

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

Re: Function declarations as statements

Garrett Smith
In reply to this post by Michael Day
On 11/11/10, Michael Day <[hidden email]> wrote:

> Hi Brendan and Allen,
>
> Thanks for the pointers.
>
>> So for Harmony, we are reclaiming function in block (must be a direct
>> child of a braced block) to bind a block-local name on block entry (so
>> hoisting lives, but only to top of block -- so you can't emulate with var
>> f = function ...).
>
> If we implemented this behaviour now, I think that would be sufficient
> to make JQuery

Arrogant bunch of lackeys.

 and Raphaël work. Here is an example from JQuery that is
> giving us trouble:
>

I am now reminded of the logo Allen proposed for ECMAScript.

> if (condition) {
>      var val, props, ... ;
>
>      function getWH() { ... this is the function ... }
>

http://bugs.jquery.com/ticket/6788

I've told them about this sort of problem and they just delete the comments.

| GarrettS commented on jquery/jquery August 26, 2010
|
| The comment has since been removed.
|
| GarrettS commented on jquery/jquery August 26, 2010
|
| The comment has since been removed.

More reasons why I do not want to have anything to do with javascript.

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

Re: Function declarations as statements

Mark S. Miller-2


On Thu, Nov 11, 2010 at 5:37 PM, Garrett Smith <[hidden email]> wrote:
On 11/11/10, Michael Day <[hidden email]> wrote:
> Hi Brendan and Allen,
>
> Thanks for the pointers.
>
>> So for Harmony, we are reclaiming function in block (must be a direct
>> child of a braced block) to bind a block-local name on block entry (so
>> hoisting lives, but only to top of block -- so you can't emulate with var
>> f = function ...).
>
> If we implemented this behaviour now, I think that would be sufficient
> to make JQuery

Arrogant bunch of lackeys.

 and Raphaël work. Here is an example from JQuery that is
> giving us trouble:
>

I am now reminded of the logo Allen proposed for ECMAScript.

> if (condition) {
>      var val, props, ... ;
>
>      function getWH() { ... this is the function ... }
>

http://bugs.jquery.com/ticket/6788

I've told them about this sort of problem and they just delete the comments.

| GarrettS commented on jquery/jquery August 26, 2010
|
| The comment has since been removed.
|
| GarrettS commented on jquery/jquery August 26, 2010
|
| The comment has since been removed.

More reasons why I do not want to have anything to do with javascript.


If it sticks, please reconsider ;). Thanks.

 

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



--
    Cheers,
    --MarkM

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