Function inside if statement?

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

Function inside if statement?

Garrett Smith
if(a) {
 function b(){ }
}

A block can contain statements. A statement can't start with the
function keyword.

Mozilla's Core JavaScript guide explains that of |b| should be
evaluated as a functionExpression, but this isn't right.
Source:
http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Functions#Conditionally_defining_a_function

What should the above code do?

Should it be:

if(a) {
 (function b(){ });
}

SHould it be a function declaration, just like a variable statement?

if(a) {
 var b;
}

Spidermonkey treats |b| as a function declaration as a statement (example).

No imlementations I know throw a SyntaxError; instead, the behavior is
implementation-specific.

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

Re: Function inside if statement?

Brendan Eich-2
On Feb 5, 2008, at 3:45 PM, Garrett Smith wrote:

> if(a) {
>  function b(){ }
> }
>
> A block can contain statements. A statement can't start with the
> function keyword.
>
> Mozilla's Core JavaScript guide explains that of |b| should be
> evaluated as a functionExpression, but this isn't right.
> Source:
> http://developer.mozilla.org/en/docs/ 
> Core_JavaScript_1.5_Reference:Functions#Conditionally_defining_a_funct
> ion

That doc is wrong. Wiki-elves, sigh.

SpiderMonkey has for about a decade implemented three kinds of  
function forms: definitions, expressions, and statements. This is an  
example of the last -- it's a function definition, syntactically,  
except produced as a child of another statement, possibly even a  
block -- a position which the ES3 grammar cannot produce a function  
definition. Only if control flow reaches the function statement does  
it bind its name.

This is an extension allowed by ES3 chapter 16.

> No imlementations I know throw a SyntaxError; instead, the behavior is
> implementation-specific.

Sure -- you knew that already by reading ES3, right? The problem with  
standardizing is diverting effort from other tasks, and then forging  
agreement on what function statements should mean. In IE, and IIRC  
Opera based solely on IE, they are function definitions -- they  
unconditionally bind their names on entry to the parent execution  
context. That seems like a mistake, but it's hard to tell given other  
IE bugs to do with named function forms (you know the one I mean well).

/be

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

Re: Function inside if statement?

liorean
In reply to this post by Garrett Smith
Just wanted to point out the thread starting here:
<uri:https://mail.mozilla.org/pipermail/es4-discuss/2007-March/000483.html>.

It discusses this issue. Brendan gave this answer, a few replies in:
> Since this is an ES3 extension, allowed by chapter 16, we could
> codify the majority-share practice, except that it sucks. We have so
> far avoided specifying function statements, preferring to leave them
> to implementations to experiment with, on into the ES4 future.



I did a summary of what the engines did in various browsers at:
<uri:https://mail.mozilla.org/pipermail/es4-discuss/2007-March/000495.html>
The discussion detours a bit after that.

Also, Microsoft included these tests as section 2.9 in their "JScript
Deviations from ES3" document at:
<uri:http://wiki.ecmascript.org/lib/exe/fetch.php?id=resources%3Aresources&cache=cache&media=resources:jscriptdeviationsfromes3.pdf>

Note that the reason Safari according to that document doesn't give
any results is that the test uses plain function declarations in the
statement bodies. If the statement bodies had been wrapped in a
statement list (curlies) then Safari would have given a profile very
similar to that of Firefox except for the
break-within-labelled-statement case, IIRC.
In other words, to do a full set of tests one need to try both the
statement-list wrapped versions and the plain function declaration
versions, because they may have differing results.
--
David "liorean" Andersson
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

RE: Function inside if statement?

mikewse
Sorry if this was already covered by your summary, but I can confirm
that
  if (true) function f() {}
yields a SyntaxError in Safari 2.0.4, while
  if (true) { function f() {} }
works fine.

Best regards
Mike

> -----Original Message-----
> From: [hidden email]
> [mailto:[hidden email]] On Behalf Of liorean
> Sent: den 6 februari 2008 01:42
> To: [hidden email]
> Subject: Re: Function inside if statement?
>
> Just wanted to point out the thread starting here:
> <uri:https://mail.mozilla.org/pipermail/es4-discuss/2007-March
> /000483.html>.
>
> It discusses this issue. Brendan gave this answer, a few replies in:
> > Since this is an ES3 extension, allowed by chapter 16, we could
> > codify the majority-share practice, except that it sucks. We have so
> > far avoided specifying function statements, preferring to leave them
> > to implementations to experiment with, on into the ES4 future.
>
>
>
> I did a summary of what the engines did in various browsers at:
> <uri:https://mail.mozilla.org/pipermail/es4-discuss/2007-March
> /000495.html>
> The discussion detours a bit after that.
>
> Also, Microsoft included these tests as section 2.9 in their "JScript
> Deviations from ES3" document at:
> <uri:http://wiki.ecmascript.org/lib/exe/fetch.php?id=resources
> %3Aresources&cache=cache&media=resources:jscriptdeviationsfromes3.pdf>
>
> Note that the reason Safari according to that document doesn't give
> any results is that the test uses plain function declarations in the
> statement bodies. If the statement bodies had been wrapped in a
> statement list (curlies) then Safari would have given a profile very
> similar to that of Firefox except for the
> break-within-labelled-statement case, IIRC.
> In other words, to do a full set of tests one need to try both the
> statement-list wrapped versions and the plain function declaration
> versions, because they may have differing results.
> --
> David "liorean" Andersson
> _______________________________________________
> Es4-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es4-discuss
>

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

Re: Function inside if statement?

P T Withington
In reply to this post by Brendan Eich-2
On 2008-02-05, at 18:53 EST, Brendan Eich wrote:

> SpiderMonkey has for about a decade implemented three kinds of
> function forms: definitions, expressions, and statements. This is an
> example of the last -- it's a function definition, syntactically,
> except produced as a child of another statement, possibly even a
> block -- a position which the ES3 grammar cannot produce a function
> definition. Only if control flow reaches the function statement does
> it bind its name.
>
> This is an extension allowed by ES3 chapter 16.

I would endorse standardizing this behavior.

FWIW, the Openlaszlo compiler/translator extends es3 in a similar  
fashion to support conditional compilation.  An `if` that tests a  
compile-time constant will be optimized away by the compiler.
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Extracting getters and setters

Michael O'Brien-4
Question about getters and setters.  Can you assign a getter / setter to
a var and invoke later?  i.e. can you extract a getter/setter method?

Consider:

class Shape {
    function get width(): int {
       return 1;
    }

    function set width(value: int): void {
    }

    /* Does this assign the getter or setter */
    var fun = width
}

var s: Shape = new Shape
s.fun()


ASC will extract the getter. But what should ES4 do? How can you extract
the getter or the setter or both?

Under the hood, is the width getter/setter to be stored as one property
or 2 and what is the property name?

Thanks

Michael O'Brien
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

RE: Extracting getters and setters

Lars Hansen-3
> -----Original Message-----
> From: [hidden email]
> [mailto:[hidden email]] On Behalf Of Michael O'Brien
> Sent: 6. februar 2008 13:06
> To: es4-discuss Discuss
> Subject: Extracting getters and setters
>
> Question about getters and setters.  Can you assign a getter
> / setter to a var and invoke later?  i.e. can you extract a
> getter/setter method?
>
> Consider:
>
> class Shape {
>     function get width(): int {
>        return 1;
>     }
>
>     function set width(value: int): void {
>     }
>
>     /* Does this assign the getter or setter */
>     var fun = width
> }
>
> var s: Shape = new Shape
> s.fun()
>
>
> ASC will extract the getter.

That's surprising to me.

> But what should ES4 do? How can
> you extract the getter or the setter or both?

I would like to argue you should not be able to.  Firefox has
facilities, methods called __getter__ and __setter__ IIRC, that extracts
them.  And I think that if ES4 allows them to be extracted that's the
only way to go.

> Under the hood, is the width getter/setter to be stored as
> one property or 2 and what is the property name?

It doesn't feel natural for the language spec to talk about that, esp if
it's not observable.

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

Re: Extracting getters and setters

Peter Hall-4
ES4 needs to treat getter/setters identically to normal vars.
Otherwise it kind of defeats the point of having them.

I would expect:

      var fun = width;

to *invoke* the getter. In that particular case, I'd expect a compile
error because width can't be accessed from static scope, exactly as if
it was declared as a var.

If implementations want to also expose __get__ properties to access
the functions, then that is up to them, but I think it's quite
important that ES4 treats getter/setters exactly like variables.

Peter


On Feb 6, 2008 10:02 PM, Lars Hansen <[hidden email]> wrote:

> > -----Original Message-----
> > From: [hidden email]
> > [mailto:[hidden email]] On Behalf Of Michael O'Brien
> > Sent: 6. februar 2008 13:06
> > To: es4-discuss Discuss
> > Subject: Extracting getters and setters
> >
> > Question about getters and setters.  Can you assign a getter
> > / setter to a var and invoke later?  i.e. can you extract a
> > getter/setter method?
> >
> > Consider:
> >
> > class Shape {
> >     function get width(): int {
> >        return 1;
> >     }
> >
> >     function set width(value: int): void {
> >     }
> >
> >     /* Does this assign the getter or setter */
> >     var fun = width
> > }
> >
> > var s: Shape = new Shape
> > s.fun()
> >
> >
> > ASC will extract the getter.
>
> That's surprising to me.
>
> > But what should ES4 do? How can
> > you extract the getter or the setter or both?
>
> I would like to argue you should not be able to.  Firefox has
> facilities, methods called __getter__ and __setter__ IIRC, that extracts
> them.  And I think that if ES4 allows them to be extracted that's the
> only way to go.
>
> > Under the hood, is the width getter/setter to be stored as
> > one property or 2 and what is the property name?
>
> It doesn't feel natural for the language spec to talk about that, esp if
> it's not observable.
>
> --lars
>
> _______________________________________________
> Es4-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es4-discuss
>
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Extracting getters and setters

Michael O'Brien-4
My screw up. You are right, it should be treated as a var and run the getter on the assignment.

The code below has flaws and ASC and ES4 tricked me up in how they are reporting differently.

So my take from this is: ES4 doesn't allow method extraction of getters and setters. Though some
implementations may allow it through other means.

Michael


Peter Hall wrote:
ES4 needs to treat getter/setters identically to normal vars.
Otherwise it kind of defeats the point of having them.

I would expect:

      var fun = width;

to *invoke* the getter. In that particular case, I'd expect a compile
error because width can't be accessed from static scope, exactly as if
it was declared as a var.

If implementations want to also expose __get__ properties to access
the functions, then that is up to them, but I think it's quite
important that ES4 treats getter/setters exactly like variables.

Peter


On Feb 6, 2008 10:02 PM, Lars Hansen [hidden email] wrote:
  
-----Original Message-----
From: [hidden email]
[[hidden email]] On Behalf Of Michael O'Brien
Sent: 6. februar 2008 13:06
To: es4-discuss Discuss
Subject: Extracting getters and setters

Question about getters and setters.  Can you assign a getter
/ setter to a var and invoke later?  i.e. can you extract a
getter/setter method?

Consider:

class Shape {
    function get width(): int {
       return 1;
    }

    function set width(value: int): void {
    }

    /* Does this assign the getter or setter */
    var fun = width
}

var s: Shape = new Shape
s.fun()


ASC will extract the getter.
      
That's surprising to me.

    
But what should ES4 do? How can
you extract the getter or the setter or both?
      
I would like to argue you should not be able to.  Firefox has
facilities, methods called __getter__ and __setter__ IIRC, that extracts
them.  And I think that if ES4 allows them to be extracted that's the
only way to go.

    
Under the hood, is the width getter/setter to be stored as
one property or 2 and what is the property name?
      
It doesn't feel natural for the language spec to talk about that, esp if
it's not observable.

--lars

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

    

  

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

Scope rules

Michael O'Brien-4
In reply to this post by Peter Hall-4
I'm trying to find the scope rules for constructor initializers and for
function parameter default values.  If someone could point me to a
document or clarify these that would be great.

I've read bits and pieces. For constructor initializers:

class Shape {
    function Shape():
       leftSide = rightSide
    {
    }

    function render(arg1 = expression) {
    }
}

In the constructor initializers, I presume the leftSide has a scope
equal to just outside the constructor and the rightSide binds to inside
the constructor. Is this right?

Also, can "this" be used in either right or left side?

For function default arguments, is the scope of the expression just
outside the function?

Michael



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

Re: Scope rules

Jeff Dyer



On 2/7/08 4:16 PM, Michael O'Brien wrote:

> I'm trying to find the scope rules for constructor initializers and for
> function parameter default values.  If someone could point me to a
> document or clarify these that would be great.
>
> I've read bits and pieces. For constructor initializers:
>
> class Shape {
>     function Shape():
>        leftSide = rightSide
>     {
>     }
>
>     function render(arg1 = expression) {
>     }
> }
>
> In the constructor initializers, I presume the leftSide has a scope
> equal to just outside the constructor and the rightSide binds to inside
> the constructor. Is this right?

'leftSide' targets the instance and so must be and instance variable.
'rightSide' has a scope that includes the constructor parameters, class
statics and scopes beyond.

>
> Also, can "this" be used in either right or left side?

Since 'this' is implied on the left side and meaningless on the right, I'd
say not be both.

>
> For function default arguments, is the scope of the expression just
> outside the function?

This has been debated recently. I don't recall that there was a resolution.
My thinking is is that default parameter expression should be scoped to the
scope just outside the function. This is how the RI currently works, FWIW.

Jd

>
> Michael
>
>
>
> _______________________________________________
> Es4-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es4-discuss

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

RE: Scope rules

Lars Hansen-3
> -----Original Message-----
> From: [hidden email]
> [mailto:[hidden email]] On Behalf Of Jeff Dyer
> Sent: 7. februar 2008 20:54
> To: Michael O'Brien; es4-discuss Discuss
> Subject: Re: Scope rules
>
>
>
>
> On 2/7/08 4:16 PM, Michael O'Brien wrote:
>
> > I'm trying to find the scope rules for constructor initializers and
> > for function parameter default values.  If someone could
> point me to a
> > document or clarify these that would be great.
> >
> > I've read bits and pieces. For constructor initializers:
> >
> > class Shape {
> >     function Shape():
> >        leftSide = rightSide
> >     {
> >     }
> >
> >     function render(arg1 = expression) {
> >     }
> > }
> >
> > In the constructor initializers, I presume the leftSide has a scope
> > equal to just outside the constructor and the rightSide binds to
> > inside the constructor. Is this right?
>
> 'leftSide' targets the instance and so must be and instance variable.
> 'rightSide' has a scope that includes the constructor
> parameters, class statics and scopes beyond.
>
> >
> > Also, can "this" be used in either right or left side?
>
> Since 'this' is implied on the left side and meaningless on
> the right, I'd say not be both.
>
> >
> > For function default arguments, is the scope of the expression just
> > outside the function?
>
> This has been debated recently. I don't recall that there was
> a resolution.
> My thinking is is that default parameter expression should be
> scoped to the scope just outside the function. This is how
> the RI currently works, FWIW.

I agree.  There's utility in left-to-right binding, but for the "let"
block statement we went with parallel bindings and I think that makes
sense for parameter lists as well.

--lars

>
> Jd
>
> >
> > Michael
> >
> >
> >
> > _______________________________________________
> > Es4-discuss mailing list
> > [hidden email]
> > https://mail.mozilla.org/listinfo/es4-discuss
>
> _______________________________________________
> Es4-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es4-discuss
>
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss