Math ugliness.

J

Jorge

You may recall that Google Chrome had been observed to be getting this
aspect of ES3 wrong (with regard to String object methods in those
cases) long before there was an ES5 (or this change had been
proposed), so for at least one of the participants in the ECMA
committee getting the change passed meant not having to fix what had
previously been a faulty script engine.

Leaving aside compatibility with ES3, is there any benefit in forcing
"this" to be an object ?
Because I see at least an advantage in not forcing it: that "this" can
be undefined.
 
R

Richard Cornford

Leaving aside compatibility with ES3, is there any benefit
in forcing "this" to be an object ?
None.

Because I see at least an advantage in not forcing it: that
"this" can be undefined.

Compatibility is the issue. For years it has been a well known and
absolute fact that in javascript - this - _always_ refers to an
object. That means that for many years people will have been writing
code that relies on the truth of that fact. This code is now likely to
be exposed to environments where - this - is no longer guaranteed to
be an object, and if it has acted on the assumption that - this - will
be it will error whenever - this - is null or undefined. And it was
finding that - this - values were string primitives when they should
have been string objects that exposed the fault in Google Chrome. If
these things weren't important then that would not have been being
reported within a couple of months of Chrome being released.

And we are not looking at a voluntary opt-in here, this is not 'strict
mode' only.

Richard.
 
J

Jorge

Compatibility is the issue. For years it has been a well known and
absolute fact that in javascript - this - _always_ refers to an
object. That means that for many years people will have been writing
code that relies on the truth of that fact. This code is now likely to
be exposed to environments where - this - is no longer guaranteed to
be an object, and if it has acted on the assumption that - this - will
be it will error whenever - this - is null or undefined. And it was
finding that - this - values were string primitives when they should
have been string objects that exposed the fault in Google Chrome. If
these things weren't important then that would not have been being
reported within a couple of months of Chrome being released.

But you'll admit that this -ES3 behaviour- is not what one would -for
many reasons- expect:

var x= 3;
Number.prototype.test= function () { return this; };
x.test() === x.test()
--> false

Yes ?
And we are not looking at a voluntary opt-in here, this is not 'strict
mode' only.

Are you sure ?
 
R

Richard Cornford

On Feb 17, 6:05 pm, Jorge wrote:
But you'll admit that this -ES3 behaviour- is not what one
would -for many reasons- expect:

Generally the handling of - this - in ES3 is found unexpected/
unintuitive by many people.
var x= 3;
Number.prototype.test= function () { return this; };
x.test() === x.test()
--> false

Yes ?

No. In an environment where the - this - value is always an object,
type-conversion from primitive for property accessors create objects
internally and temporarily during evaluation, and objects are only
equal if they share identity the expected result is the one observed.

And for someone who doesn't understand the language they are writing
having any expectations is unrealistic.
Are you sure ?

Earlier in this thread, didn't Thomas go to a great deal of effort to
show that in ES5 it is possible for - this - values to be numeric
primitives regardless of the mode?

Richard.
 
J

Jorge

On Feb 17, 6:05 pm, Jorge wrote:


Generally the handling of - this - in ES3 is found unexpected/
unintuitive by many people.



No. In an environment where the - this - value is always an object,
type-conversion from primitive for property accessors create objects
internally and temporarily during evaluation, and objects are only
equal if they share identity the expected result is the one observed.

It's totally unexpected because the left hand x is exactly the same x
as the right hand x. It's only expected behaviour after 1st scratching
your head for a -presumably long- while and 2nd having read the
related chapter of the ES3 spec. But -I guess- this won't happen
anymore in ES5: the wrapper object will be used just to lookup the
property in the appropriate .proto chain, but won't be passed on to
"this".
 
R

Richard Cornford

It's totally unexpected because the left hand x is exactly the
same x as the right hand x.

Only in as far as:-

var x = 3;
x.something = 'something';

alert(x.something); //outputs undefined.

- is unexpected because you write to and then read from the same x.
Changing the way that the - this - value works does not 'solve'
implicit type-conversion confusions.
It's only expected behaviour after 1st scratching
your head for a -presumably long- while

That sounds like a waste.
and 2nd having read the
related chapter of the ES3 spec.

Any decent book on the subject should have made the point. It is a
pity that there are so few decent books on the subject but the good
ones should explain the aspects of the language that people find
difficult to understand.
But -I guess- this won't happen anymore in ES5: the wrapper
object will be used just to lookup the property in the
appropriate .proto chain, but won't be passed on to "this".

Hence the incompatibility with ES3.

Richard.
 
D

Dmitry A. Soshnikov

[...]
some of ES5 bits are already implemented in, for example, nightly
WebKit (and Opera 10.50 alpha, IIRC).

Also if interested, almost all features of ES5 (except of "strict
mode") are implemented in Rhino 1_7R3pre: <URL: ftp://ftp.mozilla.org/pub/mozilla.org/js/>.
I use it for test - as in sources there's a runnable js-console.

/ds
 
T

Thomas 'PointedEars' Lahn

Richard said:

Yes, there is: Repeated accesses to properties of `this' would not need
repeated conversion to object, whether inside the method context or outside
(if `this' was returned and the return value re-used).


PointedEars
 
P

Peter Michaux

Hi,

Do you think -as I do- that the Math object is an ugly artifact ?

No.

Think of it as a namespace for Math functions.
(2).pow(10)
--> 1024

That is a perfect example of where message passing for (at least) Math
fails. The exponentiation function takes two arguments: base and
exponent. Neither is more important than the other. Neither is the
object to which I wish to send a message. Neither argument has state
that is or needs mutation. They are just arguments to a pure function
that has no side effects. Message passing is an inappropriate paradigm
for this sort of computation.

This looks a whole lot better:

pow(2, 10)

Adding a namespace is not significantly different:

Math.pow(2, 10)

Peter
 
J

Jorge

Changing the way that the - this - value works does not 'solve'
implicit type-conversion confusions.

That's true.
That sounds like a waste.

Oh no, you've got to whisper (wtf) in the meanwhile. Try it.
Any decent book on the subject should have made the point. It is a
pity that there are so few decent books on the subject but the good
ones should explain the aspects of the language that people find
difficult to understand.

The explanation isn't difficult to understand, it's that the behaviour
requires explanation just because it's counter-intuitive.
Hence the incompatibility with ES3.

A price to pay for moving forward ?
 
J

Jorge

Yes, there is: Repeated accesses to properties of `this' would not need
repeated conversion to object, whether inside the method context or outside
(if `this' was returned and the return value re-used).

But these are just the specs. Implementations can optimize.
IOW: "you can cheat if you don't get caught"
 
J

Jorge

No.

Think of it as a namespace for Math functions.


That is a perfect example of where message passing for (at least) Math
fails. The exponentiation function takes two arguments: base and
exponent. Neither is more important than the other. Neither is the
object to which I wish to send a message. Neither argument has state
that is or needs mutation. They are just arguments to a pure function
that has no side effects. Message passing is an inappropriate paradigm
for this sort of computation.

This looks a whole lot better:

pow(2, 10)

Adding a namespace is not significantly different:

Math.pow(2, 10)

I thought it was licit for an object's method to operate on the
object.
 
T

Thomas 'PointedEars' Lahn

Peter said:
ACK

Think of it as a namespace for Math functions.

See below.
That is a perfect example of where message passing for (at least) Math
fails.

What are you talking about? Nothing fails here.
The exponentiation function takes two arguments: base and
exponent. Neither is more important than the other.

Straw man.
Neither is the object to which I wish to send a message.

Yes, the "object" is `2' (or `(2)').
Neither argument has state that is or needs mutation.

Non sequitur. Messages do not need to cause mutation.
They are just arguments to a pure function that has no side effects.

So what?
Message passing is an inappropriate paradigm for this sort of
computation.

Several designers of other languages, in particular Smalltalk, would
disagree.
This looks a whole lot better:

pow(2, 10)

Because it is prefix instead of infix style? Efficiency considerations
aside, that is is a matter of preference. And given that in math we are
writing

10
2

to display the value of "two to the tenth power", is it not more similar
and therefore more intuititive to write (2).pow(10) in source code? I know
at least one programming language that agrees here: bash (`$((2**10))').
Adding a namespace is not significantly different:

Math.pow(2, 10)

Non sequitur. No namespace is needed where the context is clear.


PointedEars
 
L

Lasse Reichstein Nielsen

Jorge said:
But these are just the specs. Implementations can optimize.
IOW: "you can cheat if you don't get caught"

Indeed, it's quite possible to look up a property of Number.prototype
without creating a new Number object.

/L
 
T

Thomas 'PointedEars' Lahn

You would. Conforming implementations can only optimize where the
Specification does not forbid it.
Indeed, it's quite possible to look up a property of Number.prototype
without creating a new Number object.

Not in a conforming implementation of ECMAScript Edition 5. There is not
that much room to maneuver here:

| A conforming implementation of ECMAScript must provide and support all
| the types, values, objects, properties, functions, and program syntax
| and semantics described in this specification.
^^^^^^^^^^^^^


PointedEars
 
P

Peter Michaux

See below.



What are you talking about? Nothing fails here.

It fails to pass my judgment as an appropriate language/library design
for how to raise one number to the power of another number. This is a
subjective discussion.

Straw man.


Yes, the "object" is `2' (or `(2)').

No. I don't want to send a message to the object 2. I don't want to
send messages to anything. I just want the value of the power and I
want to do that by a function call.


Non sequitur. Messages do not need to cause mutation.

No they don't but that is what the paradigm was primarily designed to
do and there is no need for it here.


If something can be just a simple function then let it be just a
simple function.

Several designers of other languages, in particular Smalltalk, would
disagree.

But they were wrong.

Because it is prefix instead of infix style?

Aesthetically yes but more substantially because it is a simple
function call rather than a message passing system.

Efficiency considerations
aside, that is is a matter of preference. And given that in math we are
writing

10
2

to display the value of "two to the tenth power", is it not more similar
and therefore more intuititive to write (2).pow(10) in source code?

I wouldn't rest my argument on the idea that Mathematical notation is
good. Mathematical notation is unnecessarily complex and unclear. For
example, the following is more than unfortunate. Any Math teacher can
attest to this example causing students a lot of grief.

-1
(sin(x))

-1
sin (x)

I know
at least one programming language that agrees here: bash (`$((2**10))').



Non sequitur. No namespace is needed where the context is clear.

I'm not saying the namespacing is required. I'm saying that having to
write eight characters for the name of the function instead of three
characters isn't something to get fussed about.

Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,079
Messages
2,570,575
Members
47,207
Latest member
HelenaCani

Latest Threads

Top