From: Lasse Reichstein Nielsen on
nick <nick___(a)fastmail.fm> writes:

> Now we can use nice short object wrappers like [5] or ["blue"] and
> this will work ... not to mention I don't have to mess with String
> now, and any other primitive types I forgot about.

All this work, and we are back at the good old hack of wrapping
primitives as unit-arrays to pass them by "reference".
(I've used it in Java too, and it's still a hack).

/L
--
Lasse Reichstein Holst Nielsen
'Javascript frameworks is a disruptive technology'

From: Jorge on
On Jan 18, 2:24 am, nick <nick...(a)fastmail.fm> wrote:
>
> In a UI toolkit, a spinner control class has a property called
> "Value." Value is a pointer to an int. Another class (call it Box) has
> two properties, Top and Left, both pointers to ints. During the
> display routine, Box will draw itself according to Top and Left. The
> spinner control will show "Value" in a text box.
>
> Now, say vSpinner.Value and myBox.Top point at the same int, and
> hSpinner.Value and myBox.Left point at the same value... and lets say
> you can drag Box around, which will modify its Top and Left
> properties. Spinning the spinners will now move the box, moving the
> box will update the spinners, and everything is kept in sync. There
> you have it, useful pointers to primitive types in OOP. I hope that
> example helps?

Yep. That or just make the reference to the primitive visible -in
scope- of course... but if you insist, I have this idea:

Object.prototype.setValueOf= function (p) {
this.valueOf= function () {return p;};
return this;
};

a={}.setValueOf(27)
--> Object
a+a
--> 54
a.setValueOf(5)
--> Object
a*a
--> 25
a.setValueOf(a*10)
--> Object
a+a
--> 100
a.setValueOf("wow ")
--> Object
a+a
--> "wow wow "

:-)
--
Jorge.
From: Thomas 'PointedEars' Lahn on
nick wrote:

> Thomas 'PointedEars' Lahn wrote:
>> nick wrote:
>> ...
>> > What? Regular objects are already passed by reference,
>>
>> No, objects are not passed at all. Object *references*, which are
>> values, are passed by value, like everything else.
>>
>
> Semantics.

No. Pass-by-reference (call-by-reference) is not the same as pass-by-value
(call-by-value). (Object) references are _values_ in these languages.

> I think my meaning was clear.

Evidently it was not.

>> Object(5) is unnecessary, though. Wrapper objects that have the
>> corresponding prototype objects in their prototype chain are created
>> automatically whenever primitive convertible values are used with
>> property accessors.
>
> Right, but writing "var foo=5;" is not the same as "var foo=Object
> (5);"

It is the same as

var foo = new Number(5);

if and when `foo' is later used in a /MemberExpression/.

> In other words, "var foo=5" is like "var foo=Number(5)",

No.

> while "var foo=Object(5);" acts like "var foo=new Number(5);" would...

No.

> even though both get automatically wrapped by a wrapper object, in the
> first case foo is assigned the primitive value, instead of the
> reference to the wrapper object. In other words the automatic wrappers
> seem "temporary," while objects created with {}, [], Object(), seem to
> "stick around." I'm sure that is horribly semantically incorrect,
> though.

It is completely wrong.

That is why you should make use of the prototype chain, but not augment
Object.prototype.

> Look:
>
> ---
>
> // Set the value of current object.
> Number.prototype._set = function(value)
> {
> var v = value.valueOf();
> this.valueOf = this.toString = function() { return v; };

What a nonsense.

> return this;
> };
>
> function square(num)
> {
> num._set( num * num );
> }
>
> var x = 5;
> square(x);
> alert(x); // gives 5 -- no good

You still miss the point. `square' is _not_ a method of the wrapper object
of `5'; that is its major flaw.

> var y = new Number(5);
> square(y);
> alert(y); // gives 25 -- yay

Nobody said you should do that. In fact, it is strongly recommended
against.

> var z = Object(5);
> square(z);
> alert(z); // gives 25 -- this works too

This is strongly recommended against either.

>> > Look, I don't need a lecture on object-oriented programming
>>
>> Quite obviously you do.
>
> Excuse me but I can't imagine why you think that. Is it because my 5-
> line example code has no real world use, or because you really think
> references to primitive types have no place in OO programming?

It is because you are still using a context-less (global) function to
operate on a primitive value that you wrap into an object instead of using
the wrapper object automatically created if you call a function as method
of this object.

> Either way, I'll try to give a better example.
> In a UI toolkit, a spinner control class has a property called
> "Value." Value is a pointer to an int.

No, it is not.

> Another class (call it Box) has
> two properties, Top and Left, both pointers to ints.

No, they are not. Apparently you did not understand pointers either.

> During the display routine, Box will draw itself according to Top and
> Left. The spinner control will show "Value" in a text box.
>
> Now, say vSpinner.Value and myBox.Top point at the same int,

Nothing points to an int. Same value does not mean same memory location.

> and hSpinner.Value and myBox.Left point at the same value...

This is rather insane application design. Either one property is
superfluous or it should have a getter that retrieves the other
property's value.

> and lets say you can drag Box around, which will modify its Top and Left
> properties. Spinning the spinners will now move the box, moving the
> box will update the spinners, and everything is kept in sync. There
> you have it, useful pointers to primitive types in OOP. I hope that
> example helps?

No, your example is bogus. The primitive value that the property holds can
be easily modified with modifying the property value directly, with user-
defined setters of *the object that is the owner of the property*. That
is, the method that modifies the property value should _not_ be a method of
the value but of *the object that has it as a property*.

For it is the object (here: the spinner box) that needs to be updated in
the process, not only the property value. And it is the object that needs
to provide information as to its status and _not_ its property, so as to
hide implementation details. Because accessing implementation details
would prevent the object from being modified without the need to modify the
code that uses it.

Encapsulation and information hiding are two of the core principles of
object-oriented programming, and you have violated both in the process.


PointedEars
--
Danny Goodman's books are out of date and teach practices that are
positively harmful for cross-browser scripting.
-- Richard Cornford, cljs, <cife6q$253$1$8300dec7(a)news.demon.co.uk> (2004)
From: Cody Haines on
Jorge wrote:
> --> 25
> a.setValueOf(a*10)
> --> Object
> a+a
> --> 100
Why isn't that 500?
From: Scott Sauyet on
On Jan 18, 8:26 am, Thomas 'PointedEars' Lahn <PointedE...(a)web.de>
wrote:
> nick wrote:
>> Either way, I'll try to give a better example.
>> In a UI toolkit, a spinner control class has a property called
>> "Value." Value is a pointer to an int.
>
> No, it is not.

How could you *possibly* know the implementation of Nick's imaginary
toolkit? It's easy enough to imagine a C++ toolkit that included this
code:

int *Value

Is there something intrinsic to UI toolkits that you think disallows
such an implementation? Or do you think that since it can't be done
directly in ECMAScript it can't be done anywhere? Remember that the
whole point of this thread was of possible ways to do exactly this in
ECMAScript?


>> Another class (call it Box) has
>> two properties, Top and Left, both pointers to ints.
>
> No, they are not.  Apparently you did not understand pointers either.


Since Nick is postulating his own toolkit, and workable implementation
of his ideas are easily conceivable, how can you conclude that he
doesn't understand pointers?


>> During the display routine, Box will draw itself according to Top and
>> Left. The spinner control will show "Value" in a text box.
>
>> Now, say vSpinner.Value and myBox.Top point at the same int,
>
> Nothing points to an int.  Same value does not mean same memory location.

In any language?


>> and hSpinner.Value and myBox.Left point at the same value...
>
> This is rather insane application design.  Either one property is
> superfluous or it should have a getter that retrieves the other
> property's value.

Not if you need to be able to use spinners and boxes independently of
one another. Why not a Spinner class that takes an int pointer in one
of its constructors? It could be used like this:

Spinner vSpinner = new Spinner(myBox.Top);

What is fundamentally wrong with this?


>> and lets say you can drag Box around, which will modify its Top and Left
>> properties. Spinning the spinners will now move the box, moving the
>> box will update the spinners, and everything is kept in sync. There
>> you have it, useful pointers to primitive types in OOP. I hope that
>> example helps?
>
> No, your example is bogus.  The primitive value that the property holds can
> be easily modified with modifying the property value directly, with user-
> defined setters of *the object that is the owner of the property*.  That
> is, the method that modifies the property value should _not_ be a method of
> the value but of *the object that has it as a property*.

What do you mean by "bogus"? Do you simply think that this is a poor
design that a programmer should not implement, or that it is so
egregious that the language should not support it?

C++ certainly supports this pattern. In Java, there is no direct
equivalent, as you'd have to create small mutable wrapper objects
rather than primitives; they'd be much more burdensome to use. There
was good reason not to include any simple pointers in Java, but there
are also good reasons to use them in C++, always bearing in mind that
with great power comes great responsibility.

But if you are arguing a matter of programming taste, perhaps your
tone should be somewhat less peremptory. BTW, my day-to-day language
is Java; I'm used to these restrictions. In fact, I agree that this
design would be less than ideal, to say the least. But that does not
mean that the OP doesn't have a reason to pursue the question at hand.

-- Scott