Declarations

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

Declarations

Michael O'Brien-4
Question about declarations:

Consider:

print(Shape.x)
public class Shape { public static var x = 1; }
print(Shape.x)

fun()
function fun() { print("fun"); }


In the RI this prints:

undefined
1
fun

In ASC this prints:
1
1
fun

What happens in the RI is the class declaration seems to occur where  
it is coded. It is not being
hoisted to the top of the enclosing var block. Whereas the function  
declaration is and thus can
be called before its declaration.

Is this an RI bug or just a divergence from AS3?

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

Re: Declarations

Michael O'Brien-4
As a follow up, the following somewhat surprised me.

{
     let b = 1
     {
         function fun() {
             print("CALL: " + b)
         }
     }
}
fun()

gives:

**ERROR** EvalError: uncaught exception: ReferenceError: unresolved  
lexical reference {multiname: [ns public '']::b [ns internal '']::b  
[ns public '__ES4__']::b } (near /Users/dherman/es4/src/builtins/
Error.es:86:55-86.55)


ie. the function is hoisted to the outer var block, but does not seem  
to capture the scope chain of where it was declared and b is out of  
scope.

Is this correct or an RI bug?



On Apr 15, 2008, at 9:52 AM, Michael O'Brien wrote:

> Question about declarations:
>
> Consider:
>
> print(Shape.x)
> public class Shape { public static var x = 1; }
> print(Shape.x)
>
> fun()
> function fun() { print("fun"); }
>
>
> In the RI this prints:
>
> undefined
> 1
> fun
>
> In ASC this prints:
> 1
> 1
> fun
>
> What happens in the RI is the class declaration seems to occur where  
> it is coded. It is not being
> hoisted to the top of the enclosing var block. Whereas the function  
> declaration is and thus can
> be called before its declaration.
>
> Is this an RI bug or just a divergence from AS3?
>
> Michael

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

Re: Declarations

Jon Zeppieri-2
On Tue, Apr 15, 2008 at 1:56 PM, Michael O'Brien <[hidden email]> wrote:

> As a follow up, the following somewhat surprised me.
>
>  {
>      let b = 1
>      {
>          function fun() {
>              print("CALL: " + b)
>          }
>      }
>  }
>  fun()
>
>  gives:
>
>  **ERROR** EvalError: uncaught exception: ReferenceError: unresolved
>  lexical reference {multiname: [ns public '']::b [ns internal '']::b
>  [ns public '__ES4__']::b } (near /Users/dherman/es4/src/builtins/
>  Error.es:86:55-86.55)
>
>
>  ie. the function is hoisted to the outer var block, but does not seem
>  to capture the scope chain of where it was declared and b is out of
>  scope.
>
>  Is this correct or an RI bug?

RI bug.

http://bugs.ecmascript.org/ticket/243


>
>
>
>
>
>  On Apr 15, 2008, at 9:52 AM, Michael O'Brien wrote:
>  > Question about declarations:
>  >
>  > Consider:
>  >
>  > print(Shape.x)
>  > public class Shape { public static var x = 1; }
>  > print(Shape.x)
>  >
>  > fun()
>  > function fun() { print("fun"); }
>  >
>  >
>  > In the RI this prints:
>  >
>  > undefined
>  > 1
>  > fun
>  >
>  > In ASC this prints:
>  > 1
>  > 1
>  > fun
>  >
>  > What happens in the RI is the class declaration seems to occur where
>  > it is coded. It is not being
>  > hoisted to the top of the enclosing var block. Whereas the function
>  > declaration is and thus can
>  > be called before its declaration.
>  >
>  > Is this an RI bug or just a divergence from AS3?
>  >
>  > 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: Declarations

Michael O'Brien-4
Jon, thanks. Any thoughts on the original post?


>>> Question about declarations:
>>>
>>> Consider:
>>>
>>> print(Shape.x)
>>> public class Shape { public static var x = 1; }
>>> print(Shape.x)
>>>
>>> fun()
>>> function fun() { print("fun"); }
>>>
>>>
>>> In the RI this prints:
>>>
>>> undefined
>>> 1
>>> fun
>>>
>>> In ASC this prints:
>>> 1
>>> 1
>>> fun
>>>
>>> What happens in the RI is the class declaration seems to occur where
>>> it is coded. It is not being
>>> hoisted to the top of the enclosing var block. Whereas the function
>>> declaration is and thus can
>>> be called before its declaration.
>>>
>>> Is this an RI bug or just a divergence from AS3?
>>>
>>> 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: Declarations

Jeff Dyer
This is an RI bug too (my fault). AS3 initializes programs in a single pass,
before evaluating the top level code. The RI does both in one pass. I just
filed a bug (http://bugs.ecmascript.org/ticket/382)

Jd

On 4/15/08 11:38 AM, Michael O'Brien wrote:

> Jon, thanks. Any thoughts on the original post?
>
>
>>>> Question about declarations:
>>>>
>>>> Consider:
>>>>
>>>> print(Shape.x)
>>>> public class Shape { public static var x = 1; }
>>>> print(Shape.x)
>>>>
>>>> fun()
>>>> function fun() { print("fun"); }
>>>>
>>>>
>>>> In the RI this prints:
>>>>
>>>> undefined
>>>> 1
>>>> fun
>>>>
>>>> In ASC this prints:
>>>> 1
>>>> 1
>>>> fun
>>>>
>>>> What happens in the RI is the class declaration seems to occur where
>>>> it is coded. It is not being
>>>> hoisted to the top of the enclosing var block. Whereas the function
>>>> declaration is and thus can
>>>> be called before its declaration.
>>>>
>>>> Is this an RI bug or just a divergence from AS3?
>>>>
>>>> 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
Reply | Threaded
Open this post in threaded view
|

Re: Declarations

Michael O'Brien-4
Jeff,

Can I tease out a bit more detail. I'm not sure I agree with what the  
correct answer should be.

Lars raised the issue with "var" a while back and I think, if my  
memory serves me, the conclusion
was that the variable should be hoisted to the top of the var block,  
but the initialization statement
should execute in place.

ie.

=> declaration for y hoisted to here
print(y) // Y should exist here but be null
x = 1
var y = x // Assigment from x remains here


If the above is true for variables, should we not have the same rules  
for functions and for
classes?  ie. shouldn't class static initialization code remain inline  
where the class is defined?
I'd recommend that we make var,function and class all behave the same  
way.

Does any of the above change if enclosed in a package block? I presume  
the class declaration should
be hoisted to the top of the package block. But still, the  
initialization remain inline where the
class was declared.


Michael



On Apr 15, 2008, at 11:58 AM, Jeff Dyer wrote:

> This is an RI bug too (my fault). AS3 initializes programs in a  
> single pass,
> before evaluating the top level code. The RI does both in one pass.  
> I just
> filed a bug (http://bugs.ecmascript.org/ticket/382)
>
> Jd
>
> On 4/15/08 11:38 AM, Michael O'Brien wrote:
>
>> Jon, thanks. Any thoughts on the original post?
>>
>>
>>>>> Question about declarations:
>>>>>
>>>>> Consider:
>>>>>
>>>>> print(Shape.x)
>>>>> public class Shape { public static var x = 1; }
>>>>> print(Shape.x)
>>>>>
>>>>> fun()
>>>>> function fun() { print("fun"); }
>>>>>
>>>>>
>>>>> In the RI this prints:
>>>>>
>>>>> undefined
>>>>> 1
>>>>> fun
>>>>>
>>>>> In ASC this prints:
>>>>> 1
>>>>> 1
>>>>> fun
>>>>>
>>>>> What happens in the RI is the class declaration seems to occur  
>>>>> where
>>>>> it is coded. It is not being
>>>>> hoisted to the top of the enclosing var block. Whereas the  
>>>>> function
>>>>> declaration is and thus can
>>>>> be called before its declaration.
>>>>>
>>>>> Is this an RI bug or just a divergence from AS3?
>>>>>
>>>>> 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
Reply | Threaded
Open this post in threaded view
|

RE: Declarations

Lars Hansen-3
> -----Original Message-----
> From: [hidden email]
> [mailto:[hidden email]] On Behalf Of Michael O'Brien
> Sent: 15. april 2008 15:06
> To: Jeff Dyer
> Cc: es4-discuss Discuss; Jon Zeppieri
> Subject: Re: Declarations
>
> Jeff,
>
> Can I tease out a bit more detail. I'm not sure I agree with
> what the correct answer should be.
>
> Lars raised the issue with "var" a while back and I think, if
> my memory serves me, the conclusion was that the variable
> should be hoisted to the top of the var block, but the
> initialization statement should execute in place.
>
> ie.
>
> => declaration for y hoisted to here
> print(y) // Y should exist here but be null
> x = 1
> var y = x // Assigment from x remains here
>
>
> If the above is true for variables, should we not have the
> same rules  
> for functions and for
> classes?  ie. shouldn't class static initialization code
> remain inline  
> where the class is defined?
> I'd recommend that we make var,function and class all behave
> the same  
> way.

They don't work the same way, in ES3.  

IMO method init needs to be hoisted in classes like function
init is in ES3.  I think this is important for implementations
with vtables.

Classes are compile-time entities (with types and namespaces)
and may need to be privileged that way, in initialization terms.

More later.

--lars

>
> Does any of the above change if enclosed in a package block?
> I presume  
> the class declaration should
> be hoisted to the top of the package block. But still, the  
> initialization remain inline where the
> class was declared.
>
>
> Michael
>
>
>
> On Apr 15, 2008, at 11:58 AM, Jeff Dyer wrote:
> > This is an RI bug too (my fault). AS3 initializes programs in a  
> > single pass,
> > before evaluating the top level code. The RI does both in
> one pass.  
> > I just
> > filed a bug (http://bugs.ecmascript.org/ticket/382)
> >
> > Jd
> >
> > On 4/15/08 11:38 AM, Michael O'Brien wrote:
> >
> >> Jon, thanks. Any thoughts on the original post?
> >>
> >>
> >>>>> Question about declarations:
> >>>>>
> >>>>> Consider:
> >>>>>
> >>>>> print(Shape.x)
> >>>>> public class Shape { public static var x = 1; }
> >>>>> print(Shape.x)
> >>>>>
> >>>>> fun()
> >>>>> function fun() { print("fun"); }
> >>>>>
> >>>>>
> >>>>> In the RI this prints:
> >>>>>
> >>>>> undefined
> >>>>> 1
> >>>>> fun
> >>>>>
> >>>>> In ASC this prints:
> >>>>> 1
> >>>>> 1
> >>>>> fun
> >>>>>
> >>>>> What happens in the RI is the class declaration seems to occur  
> >>>>> where
> >>>>> it is coded. It is not being
> >>>>> hoisted to the top of the enclosing var block. Whereas the  
> >>>>> function
> >>>>> declaration is and thus can
> >>>>> be called before its declaration.
> >>>>>
> >>>>> Is this an RI bug or just a divergence from AS3?
> >>>>>
> >>>>> 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
>
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Declarations

Michael O'Brien-4
Here is a confusing example that bears it out.

var x = 1
print("x: " + x)

var y = Shape.z
print("y: " + y)

class Shape {
     public static var z = x
        print("z: " + z)
}

Currently es4 (and ejs) print:
x: 1
y: undefined
z: 1


ASC prints:
z: undefined
x: 1
y: undefined

NOTE: both values and order of execution are different.

I prefer the current es4 behavior because static class initialization  
code can predictably
use lexically scoped values. And it behaves like var declarations.

Michael O'Brien



On Apr 15, 2008, at 12:13 PM, Lars Hansen wrote:

>> -----Original Message-----
>> From: [hidden email]
>> [mailto:[hidden email]] On Behalf Of Michael O'Brien
>> Sent: 15. april 2008 15:06
>> To: Jeff Dyer
>> Cc: es4-discuss Discuss; Jon Zeppieri
>> Subject: Re: Declarations
>>
>> Jeff,
>>
>> Can I tease out a bit more detail. I'm not sure I agree with
>> what the correct answer should be.
>>
>> Lars raised the issue with "var" a while back and I think, if
>> my memory serves me, the conclusion was that the variable
>> should be hoisted to the top of the var block, but the
>> initialization statement should execute in place.
>>
>> ie.
>>
>> => declaration for y hoisted to here
>> print(y) // Y should exist here but be null
>> x = 1
>> var y = x // Assigment from x remains here
>>
>>
>> If the above is true for variables, should we not have the
>> same rules
>> for functions and for
>> classes?  ie. shouldn't class static initialization code
>> remain inline
>> where the class is defined?
>> I'd recommend that we make var,function and class all behave
>> the same
>> way.
>
> They don't work the same way, in ES3.
>
> IMO method init needs to be hoisted in classes like function
> init is in ES3.  I think this is important for implementations
> with vtables.
>
> Classes are compile-time entities (with types and namespaces)
> and may need to be privileged that way, in initialization terms.
>
> More later.
>
> --lars
>
>>
>> Does any of the above change if enclosed in a package block?
>> I presume
>> the class declaration should
>> be hoisted to the top of the package block. But still, the
>> initialization remain inline where the
>> class was declared.
>>
>>
>> Michael
>>
>>
>>
>> On Apr 15, 2008, at 11:58 AM, Jeff Dyer wrote:
>>> This is an RI bug too (my fault). AS3 initializes programs in a
>>> single pass,
>>> before evaluating the top level code. The RI does both in
>> one pass.
>>> I just
>>> filed a bug (http://bugs.ecmascript.org/ticket/382)
>>>
>>> Jd
>>>
>>> On 4/15/08 11:38 AM, Michael O'Brien wrote:
>>>
>>>> Jon, thanks. Any thoughts on the original post?
>>>>
>>>>
>>>>>>> Question about declarations:
>>>>>>>
>>>>>>> Consider:
>>>>>>>
>>>>>>> print(Shape.x)
>>>>>>> public class Shape { public static var x = 1; }
>>>>>>> print(Shape.x)
>>>>>>>
>>>>>>> fun()
>>>>>>> function fun() { print("fun"); }
>>>>>>>
>>>>>>>
>>>>>>> In the RI this prints:
>>>>>>>
>>>>>>> undefined
>>>>>>> 1
>>>>>>> fun
>>>>>>>
>>>>>>> In ASC this prints:
>>>>>>> 1
>>>>>>> 1
>>>>>>> fun
>>>>>>>
>>>>>>> What happens in the RI is the class declaration seems to occur
>>>>>>> where
>>>>>>> it is coded. It is not being
>>>>>>> hoisted to the top of the enclosing var block. Whereas the
>>>>>>> function
>>>>>>> declaration is and thus can
>>>>>>> be called before its declaration.
>>>>>>>
>>>>>>> Is this an RI bug or just a divergence from AS3?
>>>>>>>
>>>>>>> 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
>>

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

Re: Declarations

Waldemar Horwat
In reply to this post by Michael O'Brien-4
Michael O'Brien wrote:

> As a follow up, the following somewhat surprised me.
>
> {
>      let b = 1
>      {
>          function fun() {
>              print("CALL: " + b)
>          }
>      }
> }
> fun()
>
> gives:
>
> **ERROR** EvalError: uncaught exception: ReferenceError: unresolved  
> lexical reference {multiname: [ns public '']::b [ns internal '']::b  
> [ns public '__ES4__']::b } (near /Users/dherman/es4/src/builtins/
> Error.es:86:55-86.55)
>
>
> ie. the function is hoisted to the outer var block, but does not seem  
> to capture the scope chain of where it was declared and b is out of  
> scope.
>
> Is this correct or an RI bug?

This is incorrect and an RI bug, but for a different reason:  fun should be undefined in the outer scope, since it should not get hoisted out of the inner block, as we agreed at the last face-to-face meeting.

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

Re: Declarations

liorean
> Michael O'Brien wrote:
>  > As a follow up, the following somewhat surprised me.
>  >
>  > {
>  >      let b = 1
>  >      {
>  >          function fun() {
>  >              print("CALL: " + b)
>  >          }
>  >      }
>  > }
>  > fun()
>  >
>  > gives:
>  >
>  > **ERROR** EvalError: uncaught exception: ReferenceError: unresolved
>  > lexical reference {multiname: [ns public '']::b [ns internal '']::b
>  > [ns public '__ES4__']::b } (near /Users/dherman/es4/src/builtins/
>  > Error.es:86:55-86.55)
>  >
>  >
>  > ie. the function is hoisted to the outer var block, but does not seem
>  > to capture the scope chain of where it was declared and b is out of
>  > scope.
>  >
>  > Is this correct or an RI bug?

On 16/04/2008, Waldemar Horwat <[hidden email]> wrote:
> This is incorrect and an RI bug, but for a different reason:  fun should be undefined in the outer scope, since it should not get hoisted out of the inner block, as we agreed at the last face-to-face meeting.

While ES3 has that case as a SyntaxError, implementations of ES3 allow
it. SpiderMonkey (tested in JS1.7 mode) is the only browser hosted
implementation that I could find which does not hoist the function
declaration and initialisation to the top of the current function
scope at compile time. What SpiderMonkey does is that it hoists the
function to the current function scope at run time though. Which means
that:

    alert(foo);
    {
        function foo(){}
        alert(foo);
    }

is a reference error at the first line, while:

    {
        function foo(){}
        alert(foo);
    }
    alert(foo);

is not an error.

So the choice to not hoist a function declaration to function scope at
least at run time seems like it would break code written for any of
our current browser hosted implementations. I would be much more
comfortable with hoisting the declaration at compile time and doing
the initialisation at run time to preserve the relation with control
flow. (As I discussed in [1].)

Isn't it better to do what SpiderMonkey does for regular function
declarations in statements, as a lowest-common-denominator for how
widely the function declaration is accessible, and only make a
qualified block scoped function:

    {
        let function(){}
    }

to be bound in block scope?



Also another point to make about this: You are effectively adding a
function-declaration-within-statement production, something ES3 left
undefined. Browser implementations vary in how these constructs are
treated with relation to control flow and compile time vs. run time
initialisation (see [2] for a breakdown of behaviour in various
engines). If you allow it at all, you should be explicit about what
the rules for declaration hoisting and initialisation timing really
are - current implementations are not interoperable.

I personally prefer preserving control flow versus preserving
use-before-definition mechanics (this is more useful of the two
absolutes, and doing something like the inconsistency of
JavaScriptCore is madness), and preserving the scoping to function
level since all browser hosted implementations currently guarantee use
even after the block has exited.


[1] <uri:https://mail.mozilla.org/pipermail/es4-discuss/2007-March/000483.html>
[2] <uri:https://mail.mozilla.org/pipermail/es4-discuss/2007-March/000495.html>
--
David "liorean" Andersson
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss