Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Javascript > Closure bug

Reply
Thread Tools

Closure bug

 
 
Tim Streater
Guest
Posts: n/a
 
      05-19-2010
In article
<(E-Mail Removed)>,
Ry Nohryb <(E-Mail Removed)> wrote:

> On May 19, 3:14*am, Stefan Weiss <(E-Mail Removed)> wrote:
> > On 18/05/10 15:05, David Mark wrote:
> >
> > > The value passed is a reference to an object. *That might sound
> > > like a contradiction in terms, but consider:-

> >
> > > function test(o) {
> > > * o = null;
> > > }

> >
> > > var p = {};
> > > test(p);
> > > window.alert(p); // Not null

> >
> > I think that's a perfect illustration. It's all you need to see to
> > understand that there is no pass-by-reference in JS. (...)

>
> The same example slightly modified can be used to show that it's a
> pass-by-reference:
>
> function test (o) { o.j= "Simpson" }
> var p= {};
> test(p);
> p.j
> --> "Simpson"
>
> The question is, when you say "it's been passed by reference", what
> exactly did you expect *it* to be ?
>
> 1.- var p ?
> 2.- the value of var p (which is a reference to an object) ?
>
> And the answer is in the ES3 specs, 10.1.8, "The initial value (... of
> an argument ...) is *the*value* of the corresponding actual parameter
> supplied by the caller."
>
> So, while in JS you can't pass a reference to a var, you can't avoid
> to pass objects by reference.


You are not passing the object, you are passing a *pointer* to the
object. When you pass this *pointer*, the function makes its own copy of
the *pointer* and the original *pointer* is not modified with the test
function.

Which is why:

function test (o) { o = null; }

does *not* change p, whereas:

function test (o) { o.j= "Simpson"; }

*does* change the *object* that p points at. While test is running,
there are two pointers to the object, and only one before and after (or
at some point after, possibly).

--
Tim

"That excessive bail ought not to be required, nor excessive fines imposed,
nor cruel and unusual punishments inflicted" -- Bill of Rights 1689
 
Reply With Quote
 
 
 
 
Ry Nohryb
Guest
Posts: n/a
 
      05-19-2010
On May 19, 2:41*pm, Tim Streater <(E-Mail Removed)> wrote:
> In article
> <(E-Mail Removed)>,
> *Ry Nohryb <(E-Mail Removed)> wrote:
>
>
>
>
>
> > On May 19, 3:14*am, Stefan Weiss <(E-Mail Removed)> wrote:
> > > On 18/05/10 15:05, David Mark wrote:

>
> > > > The value passed is a reference to an object. *That might sound
> > > > like a contradiction in terms, but consider:-

>
> > > > function test(o) {
> > > > * o = null;
> > > > }

>
> > > > var p = {};
> > > > test(p);
> > > > window.alert(p); // Not null

>
> > > I think that's a perfect illustration. It's all you need to see to
> > > understand that there is no pass-by-reference in JS. (...)

>
> > The same example slightly modified can be used to show that it's a
> > pass-by-reference:

>
> > function test (o) { o.j= "Simpson" }
> > var p= {};
> > test(p);
> > p.j
> > --> "Simpson"

>
> > The question is, when you say "it's been passed by reference", what
> > exactly did you expect *it* to be ?

>
> > 1.- var p ?
> > 2.- the value of var p (which is a reference to an object) ?

>
> > And the answer is in the ES3 specs, 10.1.8, "The initial value (... of
> > an argument ...) is *the*value* of the corresponding actual parameter
> > supplied by the caller."

>
> > So, while in JS you can't pass a reference to a var, you can't avoid
> > to pass objects by reference.

>
> You are not passing the object, you are passing a *pointer* to the
> object. When you pass this *pointer*, the function makes its own copy of
> the *pointer* and the original *pointer* is not modified with the test
> function.
>
> Which is why:
>
> * function test (o) { o = null; }
>
> does *not* change p, whereas:
>
> * function test (o) { o.j= "Simpson"; }
>
> *does* change the *object* that p points at. While test is running,
> there are two pointers to the object, and only one before and after (or
> at some point after, possibly).


Exactly. test(p) in JS is exactly as test(&p) in C : a pointer = a
reference.
--
Jorge.
 
Reply With Quote
 
 
 
 
Thomas 'PointedEars' Lahn
Guest
Posts: n/a
 
      05-19-2010
Tim Streater wrote:

> Ry Nohryb wrote:
>> Stefan Weiss wrote:
>> > David Mark wrote:
>> > > The value passed is a reference to an object. �That might sound
>> > > like a contradiction in terms, but consider:-
>> >
>> > > function test(o) {
>> > > � o = null;
>> > > }
>> >
>> > > var p = {};
>> > > test(p);
>> > > window.alert(p); // Not null
>> >
>> > I think that's a perfect illustration. It's all you need to see to
>> > understand that there is no pass-by-reference in JS. (...)

>>
>> The same example slightly modified can be used to show that it's a
>> pass-by-reference:
>>
>> function test (o) { o.j= "Simpson" }
>> var p= {};
>> test(p);
>> p.j
>> --> "Simpson"
>>
>> The question is, when you say "it's been passed by reference", what
>> exactly did you expect *it* to be ?
>>
>> 1.- var p ?
>> 2.- the value of var p (which is a reference to an object) ?


1. But that is _not_ what happens. This has nothing to do with variables,
as you will see shortly.

>> And the answer is in the ES3 specs, 10.1.8, "The initial value (... of
>> an argument ...) is *the*value* of the corresponding actual parameter
>> supplied by the caller."
>>
>> So, while in JS you can't pass a reference to a var,


You cannot *pass* something (like a reference) to something else that cannot
be called (like a variable). That much is true.

>> you can't avoid to pass objects by reference.


No, you pass the reference value to the function (by value). How many times
has that been explained to you already, Jorge Chamorro, albeit your not
using a pseudonym back then?

/* Firebug 1.5.4: Object { j="Simpson"} */
(function (o) { o.j = "Simpson"; return o; }({}))

> You are not passing the object, you are passing a *pointer* to the
> object.


No, think twice. If it was a pointer, which it is not, it would work like
call-by-reference: it would be possible to overwrite the object by assigning
to (the identifier of) the argument (since this would require implicit
pointer referencing we could reasonably assume implicit pointer
dereferencing).

Therefore, the term "(object) reference (value)" is being used to describe
what happens instead.


PointedEars
--
Use any version of Microsoft Frontpage to create your site.
(This won't prevent people from viewing your source, but no one
will want to steal it.)
-- from <http://www.vortex-webdesign.com/help/hidesource.htm> (404-comp.)
 
Reply With Quote
 
Ry Nohryb
Guest
Posts: n/a
 
      05-19-2010
On May 19, 3:15*pm, Thomas 'PointedEars' Lahn <(E-Mail Removed)>
wrote:
> Tim Streater wrote:
> > Ry Nohryb wrote:
> >> Stefan Weiss wrote:
> >> > David Mark wrote:
> >> > > The value passed is a reference to an object. That might sound
> >> > > like a contradiction in terms, but consider:-

>
> >> > > function test(o) {
> >> > > o = null;
> >> > > }

>
> >> > > var p = {};
> >> > > test(p);
> >> > > window.alert(p); // Not null

>
> >> > I think that's a perfect illustration. It's all you need to see to
> >> > understand that there is no pass-by-reference in JS. (...)

>
> >> The same example slightly modified can be used to show that it's a
> >> pass-by-reference:

>
> >> function test (o) { o.j= "Simpson" }
> >> var p= {};
> >> test(p);
> >> p.j
> >> --> "Simpson"

>
> >> The question is, when you say "it's been passed by reference", what
> >> exactly did you expect *it* to be ?

>
> >> 1.- var p ?
> >> 2.- the value of var p (which is a reference to an object) ?

>
> 1. *But that is _not_ what happens. *This has nothing to do with variables,
> as you will see shortly.
>
> >> And the answer is in the ES3 specs, 10.1.8, "The initial value (... of
> >> an argument ...) is *the*value* of the corresponding actual parameter
> >> supplied by the caller."

>
> >> So, while in JS you can't pass a reference to a var,

>
> You cannot *pass* something (like a reference) to something else that cannot
> be called (like a variable). *That much is true.
>
> >> you can't avoid to pass objects by reference.

>
> No, you pass the reference value to the function (by value). *How many times
> has that been explained to you already, Jorge Chamorro, albeit your not
> using a pseudonym back then?


"PointedEars" is to Thomas Lahn what "Ry Nohryb" ( === rot13("El
Abuelo") ) is to Jorge Chamorro: a nick name (not a pseudo-name). My
name is as clear as an unmuddied lake, Fred, as clear as an azure sky
of deepest summer, Fred, you can rely on me, in both in the from
header of my posts and in the signature.

> * /* Firebug 1.5.4: Object { j="Simpson"} */
> * (function (o) { o.j = "Simpson"; return o; }({}))
>
> > You are not passing the object, you are passing a *pointer* to the
> > object.

>
> No, think twice. *If it was a pointer, which it is not, it would work like
> call-by-reference: it would be possible to overwrite the object by assigning
> to (the identifier of) the argument (since this would require implicit
> pointer referencing we could reasonably assume implicit pointer
> dereferencing).


To begin with pointers and C are at a much lower level than JS. In C,
a pointer is a reference to a memory location, and C -being a lower
lever language- allows you to write there whatever you want, and, in
fact, to read what is there and cast it into whatever -any other- data
type you wish, unlike in JS. E.g. you can write a struct (an object)
there and read it back as a char * or a longint, if you wish, or
viceversa.

In JS, the object that the reference points to can be overwritten, and
the reference itself, too, but you can't cast the reference to a
different data type: IOW, given a reference to an object, you can't
make it be a different thing (by casting). And in the same way that a
given memory address (pointer value) always points to the same logical
memory address, a given reference (in JS) can not be made to point to
a different object.

Thinking in terms of pointers, when in C you've got 2 different copies
of the same pointer (pointers in C, as references in JS, are passed by
copy), as when in JS you've got 2 different references to the same
object, assigning a different value to any of the pointers won't
change the other pointer, exactly as what happens in JS.

My point since day 1, is that an object is said to be passed-by-
reference when instead of copying it (as in pass-by-copy), what gets
passed is a *reference* that points to it, as is the case in JS.

You insist in that in JS the reference is a value that gets passed by
copy, and I insist in that that's exactly what C does when passing an
objectOrWhatever by reference as in functionToCall(&objectOrWhatever).

You insist in that that's not to pass by reference, and I insist in
that that's been being called so among C programmers for nearly 3
decades now.

> (...)

--
Jorge.
 
Reply With Quote
 
Ry Nohryb
Guest
Posts: n/a
 
      05-19-2010
On May 19, 5:28*pm, Ry Nohryb <(E-Mail Removed)> wrote:
>
> You insist in that that's not to pass by reference, and I insist in
> that that's been being called so among C programmers for nearly 3
> decades now.


s/NeArLy/over/ig
--
Jorge.
 
Reply With Quote
 
Ry Nohryb
Guest
Posts: n/a
 
      05-19-2010
On May 19, 5:45*pm, williamc <(E-Mail Removed)> wrote:
> On 5/18/2010 9:14 PM, Stefan Weiss wrote:
>
>
>
>
>
> > On 18/05/10 15:05, David Mark wrote:
> >> The value passed is a reference to an object. *That might sound
> >> like a contradiction in terms, but consider:-

>
> >> function test(o) {
> >> * o = null;
> >> }

>
> >> var p = {};
> >> test(p);
> >> window.alert(p); // Not null

>
> > I think that's a perfect illustration. It's all you need to see to
> > understand that there is no pass-by-reference in JS. Incidentally,
> > that's also the way it works in Java, and Java is also the source of the
> > expression "reference types" that has been thrown around here a couple
> > of times.

>
> Agreed, that the David Mark example cuts to the chase, and to me this
> close cousin example also makes it clear that o is not a reference to p


p is a var whose value is a reference to the object {}.
o is a var whose value is a copy of the value of var p whose value is
a reference to the object {}.
WRT objects, you're always passing references, by copy, but
references, unlike when passing primitive values.
--
Jorge.
 
Reply With Quote
 
Richard Cornford
Guest
Posts: n/a
 
      05-19-2010
On May 19, 4:45 pm, williamc wrote:
<snip>
> Side note: Zakas refers to non-primitive types as
>"Reference Types" in Chapter 5 of his book. This
> terminology was objected to by some here,


I don't see why, the terminology is fine, it is just the subject that
it is being applied to that is questionable. The ECMAScript "Reference
type" is the result of evaluating an Identifier and/or a property
accessor (and, theoretically, a possible result of a call to a host
function (though no examples of that actually happening have been
observed)). The act/process of converting a "Reference type" into a
value (the call to the internal GetValue function) may as easily
result in a primitive value as a non-primitive value.

> but from reading further in this thread it looks like the
> standard also uses that terminology for heuristic purposes,


Which is a very good reason for not applying the term in relation to
javascript in any way that contradicts the standard for javascript.
Doing so is likely to result in misunderstanding and confusion, even
where it does not result from misunderstanding and confusion.

> noting that Reference
> Types aren't actual ES data types.


That would depend on what you consider a 'data type' in ECMAScript.
The Reference type is an internal type that is used to explain
required behaviour. Implementations do not need to use/implement/
instantiate/etc. such a type so long as they behave as if they did.
However, when talking technically about a language that is entirely
defined in terms of its behaviour it is quite normal to accept the
existence of anything for which an implementation is required to
behave as if it exists.

Richard.
 
Reply With Quote
 
Richard Cornford
Guest
Posts: n/a
 
      05-19-2010
On May 19, 4:54 pm, Ry Nohryb wrote:
<snip>
> WRT objects, you're always passing references, by copy,
> but references, unlike when passing primitive values.


How can you tell? Specifically, how can you tall that primitives are
not implemented as structures somewhere in memory and that the values
assigned to object properties/valuables are not references to those
structures; that copying a primitive 'value' from one variable to
another does not actually involve copying a reference?

The thing is that you cannot tell. Javascript offers no operators that
will allow you to modify a primitive, so while you can observe the
modification to an object and conclude that there must be some
'referencing' mechanism that has all values that are objects
'referring' to the single object the inability to do the same test on
the primitives does not excused the possibility that exactly the same
implementation mechanism has been applied to them.

Richard.
 
Reply With Quote
 
Ry Nohryb
Guest
Posts: n/a
 
      05-19-2010
On May 19, 6:22*pm, Richard Cornford <(E-Mail Removed)>
wrote:
> On May 19, 4:54 pm, Ry Nohryb wrote:
> <snip>
>
> > WRT objects, you're always passing references, by copy,
> > but references, unlike when passing primitive values.

>
> How can you tell? Specifically, how can you tall that primitives are
> not implemented as structures somewhere in memory and that the values
> assigned to object properties/valuables are not references to those
> structures; that copying a primitive 'value' from one variable to
> another does not actually involve copying a reference?
>
> The thing is that you cannot tell. Javascript offers no operators that
> will allow you to modify a primitive, so while you can observe the
> modification to an object and conclude that there must be some
> 'referencing' mechanism that has all values that are objects
> 'referring' to the single object the inability to do the same test on
> the primitives does not excused the possibility that exactly the same
> implementation mechanism has been applied to them.


Well, yes, you're right. The observable behaviour must be as if they
were passed by copy, and it is. But then, it's observable as well that
in V8 at least the strings are not passed by copy, because, if you
copy a 100MB string to 8 different vars, V8 does *not* use 800 MB,
even though looking at the specs they should have been duplicated.
It's when you add a single char to them that they are duplicated.
--
Jorge.
 
Reply With Quote
 
Ry Nohryb
Guest
Posts: n/a
 
      05-19-2010
On May 19, 5:28*pm, Ry Nohryb <(E-Mail Removed)> wrote:
>
> (...) and C -being a lower lever language- (...)


s/lever/level/
--
Jorge
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
*bug* *bug* *bug* David Raleigh Arnold Firefox 12 04-02-2007 03:13 AM
sys.settrace closure interaction bug Scott_Marks Python 0 10-01-2006 04:25 PM
Page Closure JezB ASP .Net 1 12-03-2003 02:05 PM
Automatic closure of a CGI-generated page. Ivan Sutton Java 0 10-01-2003 05:30 PM
Perl hangs when returning lvalue closure from another lvalue closure Julian Mehnle Perl Misc 0 07-17-2003 03:13 PM



Advertisments