Question about joined function object of ECMA-262 3rd edition

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

Question about joined function object of ECMA-262 3rd edition

Shijun He
Hi, all:

First, I'm sorry because the question is mainly about es3 not es4, but
I don't know other place to get a authority answer about my question.
We are talking about closure in javascript, and we have some questions
about ECMA-262 3rd edition:
What is joined function object(ecma-262 13.1)?

The spec has given a example:

function A() {
  function B(x) { return x*x }
  return B
}

var b1 = A();
var b2 = A();

Spec says: b1 and b2 can be joined, implementation may make b1 and
b2 the same object because [[scope]] of them have no difference.

Two call of A() will produce a function from the same FunctionBody, so
they are equated and the result function objects can be joined, am I
right? What about this code:

function C(x) {
  function D() { return x*x }
  return D
}

var d1 = C(1);
var d2 = C(2);

Are these two call of A() also are equated uses of the same source?
And can d1 anb d2 be joined in this case even their [[scope]] is
different?

If they can be joined, and as the definition of joined object(13.1.2),
d1 === d2 should return true. That's so strange because d1 === d2, but
d1() != d2()

I've read spec several times, but still confused.

In fact, I tested many js engine and no implementation join b1 and b2
(and which will make b1 === b2 = true) as spec (except dmdscript, but
it not support closure at all!). I know joining them is optional, but
if there is any implementation which join them, then it and current
impl may get diff result from the same code. Example:

function A() {
  return function () {
    return arguments.callee.test;
  }

}

var x = A();
var y = A();
x.test = 1;
y.test = 2;
print(x == y);
print(x());
print(y());

x and y can be joined, and their [[scope]] are equal, so impl can make
x and y the same object, so this code will print true, 2 and 2. But
current implements choose to not join them, print false, 1 and 2.

I believe optimization should never change the semantics of a program,
is joined object a  mistake of the es3 spec so that no impl support this
bug feature. Or, maybe I misunderstand the spec.

BTW, I know in spidermonkey b1.__proto__ == b2.__proto__, it some like
joined function, but they are not real joined object because b1 != b2.

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

Re: Question about joined function object of ECMA-262 3rd edition

John Cowan
Shijun He scripsit:

> function A() {
>   function B(x) { return x*x }
>   return B
> }
>
> var b1 = A();
> var b2 = A();
>
> Spec says: b1 and b2 can be joined, implementation may make b1 and
> b2 the same object because [[scope]] of them have no difference.
>
> Two call of A() will produce a function from the same FunctionBody, so
> they are equated and the result function objects can be joined, am I
> right?

It is not because b1 and b2 come from the same FunctionBody, but because
the function B has no persistent state, that they can be joined (which
is just a way of saying they are the same object).  Because A has no
local variables, B doesn't have to care that it was nested inside A.

> function C(x) {
>   function D() { return x*x }
>   return D
> }
>
> var d1 = C(1);
> var d2 = C(2);
>
> Are these two call of A() also are equated uses of the same source?

No.  In this case, d1 and d2 have to be different objects, because they
have different persistent states:  within d1, the variable x (which is
free in D) is bound to 1, but within d2, the variable x is bound to 2.
Thus d1 and d2 must be different objects.

In the A-B case, it is not a requirement that b1 and b2 are the same
object, but interpreters are permitted to make this optimization to
save on allocation.  Whether any of them actually do the optimization
is another question.  It may be more trouble than it's worth.  However,
a proper ES compiler would probably want to do so.

--
We call nothing profound                        [hidden email]
that is not wittily expressed.                  John Cowan
        --Northrop Frye (improved)
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Question about joined function object of ECMA-262 3rd edition

liorean
> Shijun He scripsit:
> > function A() {
> >   function B(x) { return x*x }
> >   return B
> > }
> >
> > var b1 = A();
> > var b2 = A();
> >
> > Spec says: b1 and b2 can be joined, implementation may make b1 and
> > b2 the same object because [[scope]] of them have no difference.
> >
> > Two call of A() will produce a function from the same FunctionBody, so
> > they are equated and the result function objects can be joined, am I
> > right?

On 26/07/07, John Cowan <[hidden email]> wrote:
> It is not because b1 and b2 come from the same FunctionBody, but because
> the function B has no persistent state, that they can be joined (which
> is just a way of saying they are the same object).  Because A has no
> local variables, B doesn't have to care that it was nested inside A.

A could have any number of local variables, b1 and b2 could still be
joined. The important factor is that it doesn't use variables from the
containing scope(s), so there is no observable difference.

> Shijun He scripsit:
> > function C(x) {
> >   function D() { return x*x }
> >   return D
> > }
> >
> > var d1 = C(1);
> > var d2 = C(2);
> >
> > Are these two call of A() also are equated uses of the same source?

On 26/07/07, John Cowan <[hidden email]> wrote:
> No.  In this case, d1 and d2 have to be different objects, because they
> have different persistent states:  within d1, the variable x (which is
> free in D) is bound to 1, but within d2, the variable x is bound to 2.
> Thus d1 and d2 must be different objects.

Only because they actually use the variable x, however. They don't
have to have identical scope to be joined, but they have to be
outwardly indistinguishable. Any nested function which only uses
variables from it's own variable object can be joined. It's also
possible to join function objects in some cases where they do use
variables other than from their own variable object, given that all
variables used are guaranteed to be the same - while doing this
joining is a memory footprint optimisation, it will make for more
complex (i.e. slower) compilers however.

On 26/07/07, John Cowan <[hidden email]> wrote:
> In the A-B case, it is not a requirement that b1 and b2 are the same
> object, but interpreters are permitted to make this optimization to
> save on allocation.  Whether any of them actually do the optimization
> is another question.  It may be more trouble than it's worth.  However,
> a proper ES compiler would probably want to do so.

If any implementation would chose to do the joined objects behaviour,
are they not more likely to actually just use a reference to the same
function object instead of joining two different objects? Joining
different function objects doesn't make sense if you can actually use
the same object - after all, each removal or addition of a property on
a joined function object will take extra time depending on how many
other function objects it's joined to, each creation of a joined
function object will require one enumeration of all properties of the
original function object, and each joined function object will take up
memory.

However, I think the compiler complexity added for implementing this
will give a negliable reduction in footprint, so most implementors
haven't found it worthwile to do it.
--
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: Question about joined function object of ECMA-262 3rd edition

John Cowan
liorean scripsit:

> A could have any number of local variables, b1 and b2 could still be
> joined. The important factor is that it doesn't use variables from the
> containing scope(s), so there is no observable difference.

Yes, that is what I meant.

> If any implementation would chose to do the joined objects behaviour,
> are they not more likely to actually just use a reference to the same
> function object instead of joining two different objects?

Quite so; as I said, the difference between joined and being the same
is irrelevant in this context, and indeed an internal detail of the
implementation.

> However, I think the compiler complexity added for implementing this
> will give a negliable reduction in footprint, so most implementors
> haven't found it worthwile to do it.

So far.  Eventually, someone will write an "ahead-of-time" compiler
in the style of typical Lisp compilers, where such things matter.

--
My confusion is rapidly waxing          John Cowan
For XML Schema's too taxing:            [hidden email]
    I'd use DTDs                        http://www.ccil.org/~cowan
    If they had local trees --
I think I best switch to RELAX NG.
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Question about joined function object of ECMA-262 3rd edition

Neil Mix
Wait, am I following this correctly in that:

function A() {
        function B() {}
        return B;
}

var x = A();
var y = A();

x.foo = 1;
y.foo = 2;

alert(x.foo + y.foo);

would show "3" in current compliant implementations, but  
theoretically in the future an implementation could exist that would  
show "4" and *still be compliant*?  If I'm surmising correctly, then  
that seems...buggy.

On Jul 26, 2007, at 4:33 PM, John Cowan wrote:

> liorean scripsit:
>
>> A could have any number of local variables, b1 and b2 could still be
>> joined. The important factor is that it doesn't use variables from  
>> the
>> containing scope(s), so there is no observable difference.
>
> Yes, that is what I meant.
>
>> If any implementation would chose to do the joined objects behaviour,
>> are they not more likely to actually just use a reference to the same
>> function object instead of joining two different objects?
>
> Quite so; as I said, the difference between joined and being the same
> is irrelevant in this context, and indeed an internal detail of the
> implementation.
>
>> However, I think the compiler complexity added for implementing this
>> will give a negliable reduction in footprint, so most implementors
>> haven't found it worthwile to do it.
>
> So far.  Eventually, someone will write an "ahead-of-time" compiler
> in the style of typical Lisp compilers, where such things matter.
>
> --
> My confusion is rapidly waxing          John Cowan
> For XML Schema's too taxing:            [hidden email]
>     I'd use DTDs                        http://www.ccil.org/~cowan
>     If they had local trees --
> I think I best switch to RELAX NG.
> _______________________________________________
> 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: Question about joined function object of ECMA-262 3rd edition

Shijun He
On 7/27/07, Neil Mix <[hidden email]> wrote:

> Wait, am I following this correctly in that:
>
> function A() {
>        function B() {}
>        return B;
> }
>
> var x = A();
> var y = A();
>
> x.foo = 1;
> y.foo = 2;
>
> alert(x.foo + y.foo);
>
> would show "3" in current compliant implementations, but
> theoretically in the future an implementation could exist that would
> show "4" and *still be compliant*?  If I'm surmising correctly, then
> that seems...buggy.
>

That's why I am confused...

Moreover, the spec says (13.1.2):

NOTE Two or more objects joined to each other are effectively
indistinguishable except that they may have different internal
properties. The only such internal property that may differ in this
specification is [[Scope]].

As I understand, that means, if x and y are joined, then:
x === y returns true, but
x() == y() may return false, because their [[Scope]] may differ.
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Question about joined function object of ECMA-262 3rd edition

Shijun He
I also post the question in the google groups such as
comp.lang.javascript and netscape.public.mozilla.jseng.

One reponse from mozilla.dev.tech.js-engine:
http://groups.google.com/group/mozilla.dev.tech.js-engine/browse_thread/thread/16e22c189c9ea5f6/5383179969284d97#5383179969284d97

Jason Orendorff
Jul 24, 1:10 am

Yes, it was a mistake.  I think this "feature" is being dropped
for ECMAScript 4.

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

Re: Question about joined function object of ECMA-262 3rd edition

liorean
In reply to this post by Neil Mix
On 26/07/07, Neil Mix <[hidden email]> wrote:
> Wait, am I following this correctly in that:
[snip]

> var x = A();
> var y = A();
>
> x.foo = 1;
> y.foo = 2;
>
> alert(x.foo + y.foo);
>
> would show "3" in current compliant implementations, but
> theoretically in the future an implementation could exist that would
> show "4" and *still be compliant*?  If I'm surmising correctly, then
> that seems...buggy.

Yes, you're following it correctly. Yes, this feature of the spec is
"buggy", in the sense that you have two incompatible behaviours that
are both correct according to the spec. So in a way, we're fortunate
the most wide spread engines don't use joined function objects.

On 27/07/07, Shijun He <[hidden email]> wrote:

> Moreover, the spec says (13.1.2):
>
> NOTE Two or more objects joined to each other are effectively
> indistinguishable except that they may have different internal
> properties. The only such internal property that may differ in this
> specification is [[Scope]].
>
> As I understand, that means, if x and y are joined, then:
> x === y returns true, but
> x() == y() may return false, because their [[Scope]] may differ.

x()===y() may return false the same way x()===x() may return false.
Functions in JavaScript may have side effects, and the same input
doesn't necessarily give the same output in cosecutive uses of the
function.

Functions with different scope may be joined, but only if the scope
difference will lead to no externally observable difference. For
example:

    function mkFn(x){
        return function fn(y){
            return y*y;
        }
    }
    var
        fn1=mkFn(1),
        fn2=mkFn(2);

The variable x in mkFn will give no externally observable difference
in fn1 and fn2, thus fn1 and fn2 may be joined. If fn did use x
however, they couldn't be joined because then that would lead to an
externally observable difference.
--
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: Question about joined function object of ECMA-262 3rd edition

Shijun He
On 7/27/07, liorean <[hidden email]> wrote:
> x()===y() may return false the same way x()===x() may return false.
> Functions in JavaScript may have side effects, and the same input
> doesn't necessarily give the same output in cosecutive uses of the
> function.

No, I don't mean side effect, and there is no side effect in this
case. The result may be not equal just because they have diff
[[Scope]].

>
> Functions with different scope may be joined, but only if the scope
> difference will lead to no externally observable difference.

Could you point out in where the spec defines such condition?

The spec only says: ...an implementation may detect when the
differences in the [[Scope]] properties of two or more joined Function
objects are not externally observable and in those cases reuse the
same Function object rather than making a set of joined Function
objects.

My impression of it is: if the differences in the [[Scope]] are
externally observable, then the implementation can't reuse the same
object, but can make a set of joined Function objects.
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Question about joined function object of ECMA-262 3rd edition

liorean
> On 7/27/07, liorean <[hidden email]> wrote:
> > x()===y() may return false the same way x()===x() may return false.
> > Functions in JavaScript may have side effects, and the same input
> > doesn't necessarily give the same output in cosecutive uses of the
> > function.

On 27/07/07, Shijun He <[hidden email]> wrote:
> No, I don't mean side effect, and there is no side effect in this
> case. The result may be not equal just because they have diff
> [[Scope]].

The function objects may not be joined if the they are dependent on
different scopes. They may only be joined under the circumstance that
the difference in scopes does not give a difference in observable
behaviour.



> On 7/27/07, liorean <[hidden email]> wrote:
> > Functions with different scope may be joined, but only if the scope
> > difference will lead to no externally observable difference.

On 27/07/07, Shijun He <[hidden email]> wrote:

> Could you point out in where the spec defines such condition?
>
> The spec only says: ...an implementation may detect when the
> differences in the [[Scope]] properties of two or more joined Function
> objects are not externally observable and in those cases reuse the
> same Function object rather than making a set of joined Function
> objects.
>
> My impression of it is: if the differences in the [[Scope]] are
> externally observable, then the implementation can't reuse the same
> object, but can make a set of joined Function objects.

I think the meaning is rather that of: "If implementing joined
functions, engines may instead simply reuse the same function object"
than of "For this special case of joined functions, an engine may
reuse the same function object" because of the wording of the prior
and next sections.

~~~~
13.1.1 Equated Grammar Productions
•  Both uses obtained their FunctionBody from the same location in the
source text of the same ECMAScript program. This source text consists
of global code and any contained function codes according to the
definitions in section 10.1.2.
/.../

10.1.2 Types of Executable Code
There are three types of ECMAScript executable code:
•  Global code is source text that is treated as an ECMAScript
Program. The global code of a particular Program does not include any
source text that is parsed as part of a FunctionBody.
/.../
•  Function code is source text that is parsed as part of a
FunctionBody. The function code of a particular FunctionBody does not
include any source text that is parsed as part of a nested
FunctionBody. /.../
~~~~

I.e. if a nested function relies on the containing function, the code
it relies on is not part of either the global code or it's contained
function code and in other words can't be equated.

~~~~
13.2 Creating Function Objects
/ - - - /
Step 1 allows an implementation to optimise the common case of a
function A that has a nested function B where B is not dependent on A.
In this case the implementation is allowed to reuse the same object
for B instead of creating a new one every time A is called. Step 13
makes this optimisation optional; an implementation that chooses not
to implement it will go to step 2.
~~~~

Note "where B is not dependent on A" and "an implementation that
chooses not to implement it will go to step 2".

As I understand it, this part of the spec was written with that
particular optimisation in mind. Joined objects are just a way for the
specification to allow it.


Also, IMO it's one part of the spec that should be removed in ES4. It
makes the semantics of certain valid ES3 programs ambiguous.
--
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: Question about joined function object of ECMA-262 3rd edition

P T Withington
So, what the spec meant to say is:  If the compiler writer can think  
of an optimization that will save time or space and not break the  
semantics of Javascript, they are permitted to make that  
optimization. :)
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Question about joined function object of ECMA-262 3rd edition

Lars T Hansen-2
On 7/30/07, P T Withington <[hidden email]> wrote:

> So, what the spec meant to say is:  If the compiler writer can think
> of an optimization that will save time or space and not break the
> semantics of Javascript, they are permitted to make that
> optimization. :)

Joining is more sinister than that and several messages in this thread
have approached the problem from various angles.  The worst of it is
that side effects on function objects are unpredictable, as Neil Mix
wrote earlier.  Consider:

 function f() {
   function g() {}
   if (!("x" in g)) g.x = 12;
   g.x += 10;
   return g.x;
 }

 f();
 f();

Observe the inner function g.  By 13.1.1 bullet 1, the two uses of the
body of g are equated.  Therefore by 13.2 items 1, 13, and 14, the two
uses of g creates two objects that are joined: they have different
internal properties, but by 13.2 act as "one object" -- side effects
on one are visible on the other.

Therefore the first call to f() will return 22 but the second call may
return 22 or 32 -- either is "right".  This does not quite seem like a
feature.

What the joining spec actually means in practical terms is that "two
internal function definitions should not be used as mutable values
unless you're really careful."

-----

Normally an implementation would care about avoiding creating closures
for nested functions that are only used as functions (ie they are only
ever called, never used as values).  There are well-known techniques
for that that that do not require joining.

We haven't discussed this in the working group.  My opinion:
Implementations that perform the optimization will probably want to
continue performing it for backwards compatibility, so the behavior
may need to be brought forward for that reason.  But only if there are
important implementations that do perform it; I haven't tested and I
haven't asked.  I'm guessing the language is in there because some
implementation did perform it, at the time the previous spec was
written.

Input from members of the ES3 committee would be helpful at this
point.  The text does not appear in ES1 or ES2.

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

Re: Question about joined function object of ECMA-262 3rd edition

P T Withington
On 2007-07-31, at 07:52 EDT, Lars T Hansen wrote:

> On 7/30/07, P T Withington <[hidden email]> wrote:
>
>> So, what the spec meant to say is:  If the compiler writer can think
>> of an optimization that will save time or space and not break the
>> semantics of Javascript, they are permitted to make that
>> optimization. :)
>
> Joining is more sinister than that and several messages in this thread
> have approached the problem from various angles.  The worst of it is
> that side effects on function objects are unpredictable, as Neil Mix
> wrote earlier.

Indeed.  I was suggesting that the spec was broken; that it meant to  
prescribe an optimization to avoid unnecessary closures, but that it  
got it wrong (perhaps because it overlooked the mutability of the  
function object itself?).  Surely backwards compatibility should not  
trump correctness?  You don't want to have to force users to contrive  
to create a closure just to be able to add properties to a function?

Oh.  Ha, ha.  Now I understand a piece of code in our runtime that  
did exactly that (since removed).  I think the test case you are  
looking for might be the SWF version 5 interpreter.
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Question about joined function object of ECMA-262 3rd edition

Brendan Eich-2
On Jul 31, 2007, at 5:41 AM, P T Withington wrote:

> Indeed.  I was suggesting that the spec was broken; that it meant to
> prescribe an optimization to avoid unnecessary closures, but that it
> got it wrong (perhaps because it overlooked the mutability of the
> function object itself?).  Surely backwards compatibility should not
> trump correctness?  You don't want to have to force users to contrive
> to create a closure just to be able to add properties to a function?

No, none of that (breaking backward compatibility, requiring closures  
for mutability) was desired.

I wasn't around for Edition 3 except for one or two meetings (pitched  
sharp variables and uneval/toSource), but I talked to Waldemar about  
this at some point. The goal was to allow an optimization that would  
be implementation dependent. I believe mutability was forgotten. So  
we should just remove all this joined function language.

/be

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

Re: Question about joined function object of ECMA-262 3rd edition

Shijun He
In reply to this post by liorean
On 7/27/07, liorean <[hidden email]> wrote:
> Functions with different scope may be joined, but only if the scope
> difference will lead to no externally observable difference.

I would like to say my opinion again: though your words is very
reasonable, and I believe that may be the original meaning of the
authors of es3, but I can't read it from the specification. The spec
only say if there is no observable diff, then the impl could not only
join them but also use the same object at all.

You know english is not my native language, so may be I misunderstand it.
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Question about joined function object of ECMA-262 3rd edition

liorean
On 04/08/07, Shijun He <[hidden email]> wrote:
> On 7/27/07, liorean <[hidden email]> wrote:
> > Functions with different scope may be joined, but only if the scope
> > difference will lead to no externally observable difference.
>
> I would like to say my opinion again: though your words is very
> reasonable, and I believe that may be the original meaning of the
> authors of es3, but I can't read it from the specification. The spec
> only say if there is no observable diff, then the impl could not only
> join them but also use the same object at all.

You're right, the specification doesn't say it outright. The
specification is made for implementators though. The implementing
joined functions for *more* than the special case of when the
difference is not externally observable is not possible without
breaking the semantics of the scoping and closure mechanisms of the
language.

In fact, even joined functions for the special case of no externally
observable differences is tricky - if "externally observable" only
refers to variable scoping, then certain valid ES3 programs *will*
have ambiguous semantics - those programs that use global objects or
the joined function object itself as storage. Both Neil Mix and Lars T
Hansen gave examples which show the ambiguity of the language due to
allowing joined function objects even in the case of only doing them
for the case of no externally observable differences.

> You know english is not my native language, so may be I misunderstand it.

No, you don't misunderstand it. I just read more between the lines than you do.
--
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: Question about joined function object of ECMA-262 3rd edition

Shijun He
I read your post again today. And I found the key point is the
definition of "Equated".

13.1.1
Both uses obtained their FunctionBody from the same location in the
source text of the same ECMAScript program. This source text consists
of global code and any contained function codes according to the
definitions in section 10.1.2.

Q1: what is "source text of the same ECMAScript program" or "this source text"?
Q2: what is global code and what is contained function codes?

Let's give a example here:

function A() {
  return function B(x) {
    return x * x;
  }
}
var b1 = A();
var b2 = A();

Is the "source text" means all code or just means "return x * x"?
I think it means all codes, then the global code of it is:
  function A() {...}
  var b1 = A();
  var b2 = A();
The contained function codes are:
  return function B(x) {...}
and
  return x * x;

You said: "if a nested function relies on the containing function, the code
it relies on is not part of either the global code or it's contained
function code"

So I don't understand it. Do you mean the source text should be "return x * x"?
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Question about joined function object of ECMA-262 3rd edition

Shijun He
In reply to this post by Brendan Eich-2
In my opinion, the optimisation such as closure prototype in the
spidermonkey is enough and joined function optimisation is useless
(and wrong). If the developer want reuse the same function object,
they can write like this:

function A() {
...
}
A.B = function (x) {
  return x * x;
}

On 8/1/07, Brendan Eich <[hidden email]> wrote:
> No, none of that (breaking backward compatibility, requiring closures
> for mutability) was desired.
>
> I wasn't around for Edition 3 except for one or two meetings (pitched
> sharp variables and uneval/toSource), but I talked to Waldemar about
> this at some point. The goal was to allow an optimization that would
> be implementation dependent. I believe mutability was forgotten. So
> we should just remove all this joined function language.
>
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Question about joined function object of ECMA-262 3rd edition

liorean
In reply to this post by Shijun He
On 05/08/07, Shijun He <[hidden email]> wrote:
> I read your post again today. And I found the key point is the
> definition of "Equated".

Yeah, but my argument was flawed since the spec never actually says
what I read out from it.

> 13.1.1
> Both uses obtained their FunctionBody from the same location in the
> source text of the same ECMAScript program. This source text consists
> of global code and any contained function codes according to the
> definitions in section 10.1.2.
>
> Q1: what is "source text of the same ECMAScript program" or "this source text"?

"this source text" refers to this: "... FunctionBody from the same
location in the source text of the same ECMAScript program"

"the same location in the source text of the same ECMAScript program"
refers to the source code being from the same place in the same
program (or file), not different places in the same program, or from
different programs.

> Q2: what is global code and what is contained function codes?

I included the definition of global code and function code right after
the equated grammar productions quote:

~~~~
10.1.2 Types of Executable Code
There are three types of ECMAScript executable code:
•  Global code is source text that is treated as an ECMAScript
Program. The global code of a particular Program does not include any
source text that is parsed as part of a FunctionBody.
/.../
•  Function code is source text that is parsed as part of a
FunctionBody. The function code of a particular FunctionBody does not
include any source text that is parsed as part of a nested
FunctionBody. /.../
~~~~

Global code is straightly as defined. By "any contained function
codes" they refer to the function codes of the functions that are
joined, and from the use of the word "any" presumably their nested
function codes as well.

> Let's give a example here:
>
> function A() {
>   return function B(x) {
>     return x * x;
>   }
> }
> var b1 = A();
> var b2 = A();
>
> Is the "source text" means all code or just means "return x * x"?
> I think it means all codes, then the global code of it is:
>   function A() {...}
>   var b1 = A();
>   var b2 = A();
> The contained function codes are:
>   return function B(x) {...}
> and
>   return x * x;
>
> You said: "if a nested function relies on the containing function, the code
> it relies on is not part of either the global code or it's contained
> function code"
>
> So I don't understand it. Do you mean the source text should be "return x * x"?

The contained function code of B is "return x * x", yes, and the
joined functions are B, but from different calls to A, so they have
different [[Scope]]. Now, consider this code:

    function A(y) {
        return function B(x) {
            return x * y;
        }
    }
    var
        b1 = A(1),
        b2 = A(2);

Here the contained function code of B is "return x * y". The function
bodies are in the terms of ES3 equated - their only difference is
[[Scope]]. Which means that b1 and b2 formally may be joined here, but
an implementation cannot reuse the same function object since the y
variable from closure is used (i.e.B depends on the containing
function A). The engine would have to actually implement the joining
mechanism or some equivalent*.

My argument was wrong here - since y is part of A's variable object
and not B's variable object, I considered it part of the containing
function code (A's code). But it really isn't, so the flaw in my
argument.

* Actually implementing the joining mechanism is not an optimisation
by any means - I cannot see it actually improving the engine in any
area, neither memory footprint, byte code size nor performance. The
optimisation lies in the cases where you can skip having different
objects at all, not in the case of having two objects that are always
in sync. Keeping two distinct but identical objects in sync after they
have been created is a net loss performance wise and footprint wise,
not a net gain. Every change to a propety of one of the joined
function objects have to be duplicated on the other object.
--
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: Question about joined function object of ECMA-262 3rd edition

Shijun He
In reply to this post by P T Withington
Do you mean Flash 5 ActionScript implement joined function? I have
downloaded flash 5, but this old software can't be installed on win
xp...

On 7/31/07, P T Withington <[hidden email]> wrote:
> Oh.  Ha, ha.  Now I understand a piece of code in our runtime that
> did exactly that (since removed).  I think the test case you are
> looking for might be the SWF version 5 interpreter.
>
_______________________________________________
Es4-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es4-discuss