Math ugliness.

T

Thomas 'PointedEars' Lahn

Peter said:
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.

It is rather pointless rambling on your part.
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.

Then you should use a programming language that is either procedural or
functional, but not also object-oriented. Sending messages to objects is a
core principle of the object-oriented paradigm.

In fact, it is rather debatable whether there should be such a thing like
primitive values as opposed to object values in an object-oriented
programming language. FWIW, Brendan Eich agrees with that in his blog.
Non sequitur. Messages do not need to cause mutation.

No they don't but that is what the paradigm was primarily designed to
do [...]
Nonsense.

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

Following this reasoning you would need to object to Math.pow(...), too.
But they were wrong.

According to whom, and because of what?
Aesthetically yes but more substantially because it is a simple
function call rather than a message passing system.

Sounds pretty much like circular reasoning.
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. [...]

Sorry, you have not the shadow of a clue what you are talking about.
-1
(sin(x))

-1
sin (x)

I rest my case.
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.

If your reasoning was consistent, you would *need* to get fussed about to
begin with.

But, you do not really have a point; you are just rambling here.

Anyhow, please trim your quotations to the relevant minimum next time.


PointedEars
 
L

Lasse Reichstein Nielsen

Thomas 'PointedEars' Lahn said:
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.
^^^^^^^^^^^^^

The semantic algorithms of the specification are descriptive. The only
thing that matters is their observable behavior, not their internal
implementation details. Creating an object is only observable if a
reference to the object escapes.

In the case of the object created in the internal [[Get]] method used
by GetValue with a primitive base, it is not visible outside the
[[Get]] method. Therefore, if an implementation can achieve the same
observable behavior without actually creating the object, then it
is free to do so. One way of doing that would be to not use ToObject
in step one, but instead let O be one of Number.prototype,
String.prototype or Boolean.prototype, depending on the primitive type
of base.
Since a newly created Number object has no (non-internal) properties
of its own, its properties will be identical to those of its
prototype.

Or, to quote ES5 8.7.1:
"The object that may be created in step 1 is not accessible outside of
the above method. An implementation might choose to avoid the actual
creation of the object."

/L
 
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.

Did you have to build it? `ant compile` fails here (on Snow Leopard),
and js.jar that's in the root says "Rhino 1.7 release 2 2009 03 22"

Seems, you downloaded the older release (R2), but in R3pre using .jar
I have:

| Rhino 1.7 release 3 PRERELEASE 2010 01 14

where all this stuff with Object.: create, seel, freeze,
getPrototypeOf, property descriptors and so on is available.

Direct link: <URL: ftp://ftp.mozilla.org/pub/mozilla.org/js/rhino1_7R3pre.zip>

I'm not sure how to do this in MacOS, but in WinXP I've just
created .bat-file with:

java -jar js.jar

and run it.

Also it's possible to pass a source file as argument.

/ds
 
J

Jorge

(...)
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.

Math.floor(Math.random()*100)) vs. (100).rnd().floor()

Math.pow(Math.sin(∂),2) vs. ∂.sin().pow(2)
 
T

Thomas 'PointedEars' Lahn

Lasse said:
Thomas 'PointedEars' Lahn said:
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.
^^^^^^^^^^^^^

[...] to quote ES5 8.7.1:
"The object that may be created in step 1 is not accessible outside of
the above method. An implementation might choose to avoid the actual
creation of the object."

ACK


PointedEars
 
D

Dmitry A. Soshnikov

On Feb 17, 1:10 pm, Thomas 'PointedEars' Lahn <[email protected]>
wrote:



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.

Well, then objectively nothing can prevent you, you can easily use the
mathematical function paradigm, where's the function is the center, is
the thing with the main role, and arguments - just a "helpers" which
help to show the result of that center.

But that's questionable.

In OOP-paradigm numbers (regardless implementation on low level) also
can be presented as objects. And then you can just ask (to send the
message waiting the reply) this object: "Can you provide the value of
the 10 prower of *yourself*?"

Here already object is the center, and functions ("technique",
methods) - are "helpers" for getting the result.
If something can be just a simple function then let it be just a
simple function.

Abstractly in most implementations (of OOP paradigm) any simple
function is just a member of some object.

But repeat, this is questionable, where to put this mathematical
methods - directly in to the numbers, or into the separate namespace.
Mentioned above Ruby, e.g. has some methods in numbers, such as:

1.5.round
0.5.ceil

2**10 # which is the value of the power

and also there's the Math module also, which is the container for
other mathematical stuff, such as .sin, .cos and so on:

Math.sin(a)

Why it's still possible to have a Math module - because mathematics
works also works with higher abstractions than just a numbers (for
example, matrix, integrals and so on, although for this usually
additional namespace (or separate module) is provided).

So, in OOP paradigm the object is full-right entity which can provide
related results itself (independently how it will do it on
implementation level, will it ask the same Math.pow, or something
other - that's abstraction for you). And numbers in object abstraction
are full-right objects which play on their field - on field of
numbers. And if numbers are related to mathematics, that number
objects can *know* something about mathematics, and *use* the
mathematics - that's a vice verse when mathematics uses numbers.

So, you can easily ask: "You are number. Can you get the value of the
power of yourself?"

And can (in any other paradigm): "You are Math. Can you provide the
value of the power of that two (unknown) numbers?"

/ds
 
R

Richard Cornford

On Feb 17, 8:25 pm, Richard Cornford wrote:


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

I would have to question whether any aspect of computer programming is
actually intuitive. To illustrate; would you be able to provide a
worthwhile question on the subject of computer programming that I
could take with me to the lobby and ask our office receptionist, and
then Sam would be able to give me the correct answer based on her
intuition about the subject?

When we, as more or less experienced 'programmers', have intuitions
about the subject I would maintain that they are mostly based on
expectations acquired through experience. Usually experience with
related subjects, particularly other programming languages. Different
experiences lead people to have different expectations, and so
different intuitions about how things should work. For example, on
this page:-

<URL: http://wtfjs.com/page/2 >

- the example:-

| "string" instanceof String; // false.
|
| // 'course it isn't not a string, it may look like a string
| // but actually it's masquerading as a banana.

- appears. Now, for someone experienced in Java expecting "string" to
result in a string object, which should then be and - instanceof -
String, is second nature, while someone only experienced in assembly
language programming might have no expectations about the nature of
string literal representations (objects or not), no idea about what -
String - referred to, and no attitude towards what an - instanceof -
operator should be doing. So you have one person who would declare the
above wrong, and another who sees the need to do some research and so
likely will end up seeing it as correct.

There was a time when the majority of people coming anew to javascript
where Java programmers, and so a feeling that javascript to change to
become more Java-like so that it would accommodate their expectations/
intuitions better (hence ES4). These days I would judge the largest
single group coming into javascript have previous PHP experience, and
so expectations built on what PHP does. Ultimately the lesson that
should be taken is that no programming language can be all things to
all people, and so each should be understood in its own terms.
A price to pay for moving forward ?

Given the number of incompatible changes that are opt-in in strict
mode only, why should this one be hoisted upon everyone? A price will
be paid, but it could have been a voluntary action under the control
of web developers and paid on their time-scale.

Richard.
 
J

John G Harris

Peter Michaux wrote:


Then you should use a programming language that is either procedural or
functional, but not also object-oriented. Sending messages to objects is a
core principle of the object-oriented paradigm.

What a load of codswallop.

In fact, it is rather debatable whether there should be such a thing like
primitive values as opposed to object values in an object-oriented
programming language.

Literals are pure values. They don't exist until they're assigned to
something. To say that they can be sent messages is pure nonsense.

FWIW, Brendan Eich agrees with that in his blog.

Yet another appeal to authority.


Following this reasoning you would need to object to Math.pow(...), too.

Why ? Math is just a container of simple functions.


But, you do not really have a point; you are just rambling here.
<snip>

Pot, meet Kettle.

John
 
T

Thomas 'PointedEars' Lahn

John said:
Literals are pure values. They don't exist until they're assigned to
something. To say that they can be sent messages is pure nonsense.

Evidence readily proves you wrong.
Yet another appeal to authority.

Of course not; I would not have written "FWIW" then. In an object-oriented
programming language, primitive types that have no intrinsical relation to
each another or to object types do not really make sense. What follows
from making that distinction are, for example, the inefficiencies of
conversion that occur whenever a primitive value is used as the first part
of a /MemberExpression/, as we have just seen.

It is only the procedural-imperative paradigm and the idea of compatibility
that causes primitive types to exist is such a language. Brendan Eich,
*among several other people*, has recognized that to be a mistake for
JavaScript years ago, and he has suggested that all types should be object
types, to remove the rather _useless_ duality of Number vs. new Number(),
for example:

<http://weblogs.mozillazine.org/roadmap/archives/2005/11/>

There are other procedural-imperative object-oriented programming languages
that have already implemented this, most notably Python.
Why ? Math is just a container of simple functions.

An object does not contain functions. `Math' is a reference to an object.
Methods (a property of that object with a callable value) are called on
that object without the object being specified to be used other than as a
reference point for the function.

If one objects to (1).pow(2) on the grounds that it is unnecessary because
only a function with two arguments is required, if their reasoning would be
consistent they would need to object to Math.pow(1, 2) even more, because,
following that reasoning, pow(1, 2) would need to suffice.


PointedEars
 
J

Jorge

Evidence readily proves you wrong.



Of course not; I would not have written "FWIW" then.  In an object-oriented
programming language, primitive types that have no intrinsical relation to
each another or to object types do not really make sense.  What follows
from making that distinction are, for example, the inefficiencies of
conversion that occur whenever a primitive value is used as the first part
of a /MemberExpression/, as we have just seen.

Inefficiencies that exist only in your head (and in the specs when
implemented literally and unwisely). But there's room for
optimization, and implementations are allowed to optimize, as Lasse
has taught you.
It is only the procedural-imperative paradigm and the idea of compatibility
that causes primitive types to exist is such a language.  Brendan Eich,
*among several other people*, has recognized that to be a mistake for
JavaScript years ago, and he has suggested that all types should be object
types, to remove the rather _useless_ duality of Number vs. new Number(),
for example:

<http://weblogs.mozillazine.org/roadmap/archives/2005/11/>

There are other procedural-imperative object-oriented programming languages
that have already implemented this, most notably Python.



An object does not contain functions.  `Math' is a reference to an object.  
Methods (a property of that object with a callable value) are called on
that object without the object being specified to be used other than as a
reference point for the function.

If one objects to (1).pow(2) on the grounds that it is unnecessary because
only a function with two arguments is required, if their reasoning would be
consistent they would need to object to Math.pow(1, 2) even more, because,
following that reasoning, pow(1, 2) would need to suffice.

That's true.
 
J

John G Harris

John G Harris wrote:

Evidence readily proves you wrong.

It's clear what 2.3 + 1.4 means, but to say that 2.3 'knows' how to
add 1.4 to itself is pure nonsense. For a start, 2.3 is not mutable.

Of course, to say that the compiler is designed to do something like
create an object holding 2.3 within itself is legitimate, but there are
still primitive values in there.

Oh, hang about, that's how the ECMAScript languages work, isn't it.

Of course not; I would not have written "FWIW" then. In an object-oriented
programming language, primitive types that have no intrinsical relation to
each another or to object types do not really make sense. What follows
from making that distinction are, for example, the inefficiencies of
conversion that occur whenever a primitive value is used as the first part
of a /MemberExpression/, as we have just seen.

It's not compulsory for the language to be designed to do automatic
constructions. For instance, where javascript and Java allow a + 1.4
the equivalent C++ expression is *a + 1.4 (note that a is a pointer).

It is only the procedural-imperative paradigm and the idea of compatibility
that causes primitive types to exist is such a language. Brendan Eich,
*among several other people*, has recognized that to be a mistake for
JavaScript years ago, and he has suggested that all types should be object
types, to remove the rather _useless_ duality of Number vs. new Number(),
for example:

<http://weblogs.mozillazine.org/roadmap/archives/2005/11/>

There are other procedural-imperative object-oriented programming languages
that have already implemented this, most notably Python.

A coherent type system has each type built from 'simpler' types, or from
foundation types. The system needs these foundation types to be able to
do proofs by induction and to define mathematical properties using
recursion. Primitive types are the foundation types.

In contrast, if you insist that every property holds an object and
nothing else then you've some complicated specifying to do in order to
put numbers and character arrays in there somewhere.

An object does not contain functions. `Math' is a reference to an object.
Methods (a property of that object with a callable value) are called on
that object without the object being specified to be used other than as a
reference point for the function.

It's well known that javascript does things differently, but you can
emulate what other languages do, sometimes rather awkwardly.

Here's a case where a namespace is being emulated by an object. It's
silly to complain about the mechanics of the emulation being visible.

<snip>

John
 
D

Dmitry A. Soshnikov

It's clear what  2.3 + 1.4  means, but to say that 2.3 'knows' how to
add 1.4 to itself is pure nonsense.

You can think that 2.3. provides new objects (what actually is) by
applying itself to other object. Statement "pure nonsense" - is
inappropriate (only if it's hard to imagine number objects
abstraction).
For a start, 2.3 is not mutable.

It may be, or may not be so, again - depends on implementation and
ideology of abstraction. What can prevent to mutate object from one
state to another, possibly applying it's previous state to some
external factor? Though, usually it creates new object based on its
state.

/ds
 
J

Jorge

<snip>




You can think that 2.3. provides new objects (what actually is) by
applying itself to other object. Statement "pure nonsense" - is
inappropriate (only if it's hard to imagine number objects
abstraction).


It may be, or may not be so, again - depends on implementation and
ideology of abstraction. What can prevent to mutate object from one
state to another, possibly applying it's previous state to some
external factor? Though, usually it creates new object based on its
state.

And it doesn't matter whether 2.3 is or isn't mutable. It's just an
object that has a method that returns a value: e.g. 2.3.floor()
 
T

Thomas 'PointedEars' Lahn

John said:
It's clear what 2.3 + 1.4 means, but to say that 2.3 'knows' how to
add 1.4 to itself is pure nonsense.

Evidence readily proves you wrong, although not in current ECMAScript
implementations.
For a start, 2.3 is not mutable.

It could be, were the language defined differently.
Of course, to say that the compiler is designed to do something like
create an object holding 2.3 within itself is legitimate, but there are
still primitive values in there.

Oh, hang about, that's how the ECMAScript languages work, isn't it.

This was about method calls, not operators, and your original statement is
still wrong.
It's not compulsory for the language to be designed to do automatic
constructions. For instance, where javascript and Java allow a + 1.4
the equivalent C++ expression is *a + 1.4 (note that a is a pointer).

I don't see your point. C++ is as much a hybrid language as are Java and
JavaScript, only that the former two are strictly typed, which is why you
cannot simply write "a + 1.4" in Java or C++ without knowing the type of
`a'.
A coherent type system has each type built from 'simpler' types, or from
foundation types. The system needs these foundation types to be able to
do proofs by induction and to define mathematical properties using
recursion. Primitive types are the foundation types.

They are unnecessary. Foundation types can be object types as well.
In contrast, if you insist that every property holds an object and
nothing else then you've some complicated specifying to do in order to
put numbers and character arrays in there somewhere.
No.


It's well known that javascript does things differently, but you can
emulate what other languages do, sometimes rather awkwardly.

Here's a case where a namespace is being emulated by an object. It's
silly to complain about the mechanics of the emulation being visible.

You miss the point.


PointedEars
 
L

Lasse Reichstein Nielsen

Thomas 'PointedEars' Lahn said:
John G Harris wrote:

Evidence readily proves you wrong, although not in current ECMAScript
implementations.

It's clear that other languages have taken the road of having math
operations that work by sending messages to one of the arguments.
In that way, it "makes sense".

When numbers are objects[1], it makes sense to have operations on that
number as methods of the number. Methods with only one parameter can
use "this" as that parameter.

However, when you have a method that take two, equally important,
parameters, and that doesn't mutate either (or really: and doesn't
depend on the identity of either), it's not obvious which of them
should carry the method.
In those cases, it makes just as much sense, and perhaps more -
because it doesn't make an arbitrary choice - to put the method
on a separate object.

E.g., a function that repeats a string a number of times.
It could be either
Number::repeatString(String): String
or
String::repeatString(Number): Number
but it could just as well be
StringFactory::repeatString(String,Number): String
In languages with something like static methods, StringFactory
would typically be the String class object.
It could be, were the language defined differently.

Then it would not be a 2.3 object, but just a boxed number.
If you did:
var x = 2.3;
var y = 2.3;
and 2.3 was mutable ... would x.mutate() mean that the value of
y changed? Or did the two 2.3's have different identity?
They are unnecessary. Foundation types can be object types as well.

Correct. And they were in, e.g., Smalltalk.
It's quite possible to both do this and optimize it to avoid actually
allocating space for a separate object for each number.

The choice of foundation types also differ. In ECMAScript, string
is a primive, in Java it is an Object. Nothing prevents numbers
from being objects as well (semantically).

Instead we have the weird distinction in Java where you can't put
unboxed primitives into collections, which is quite often what
you really want to do.

ECMAScript fares a little easier, because we don't have a type system
that distinguishes objects and primitves, and we can call methods on
primitives. With ES5, we don't really need the wrapper classes for
anything any more, except as a specification tool.

Agree, that's an implementation problem, not a specification problem,
and it has been shown possible to implement.

/L
 
J

John G Harris

Thomas 'PointedEars' Lahn said:
John G Harris wrote:

Evidence readily proves you wrong, although not in current ECMAScript
implementations.

It's clear that other languages have taken the road of having math
operations that work by sending messages to one of the arguments.
In that way, it "makes sense".

When numbers are objects[1], it makes sense to have operations on that
number as methods of the number. Methods with only one parameter can
use "this" as that parameter.

However, when you have a method that take two, equally important,
parameters, and that doesn't mutate either (or really: and doesn't
depend on the identity of either), it's not obvious which of them
should carry the method.

Alternatively, you could make + an object, a function object. That makes
much more sense as you would expect + to know about numbers and how to
take two numbers and return another number. No mutation of immutable
things here.

Whether you can access the + object is a matter of language design. You
can in some languages, but they tend to spell it 'add' :-(

Incidentally, you seem to have missed out your [1] text.


Then it would not be a 2.3 object, but just a boxed number.
If you did:
var x = 2.3;
var y = 2.3;
and 2.3 was mutable ... would x.mutate() mean that the value of
y changed? Or did the two 2.3's have different identity?

Or y = x; even more so.

Correct. And they were in, e.g., Smalltalk.

Every object has a value, which now can only be an object. The result is
that you have objects all the way down, for ever.

This disaster can only be rescued by having an object that doesn't have
a value. That becomes the foundation object.


Agree, that's an implementation problem, not a specification problem,
and it has been shown possible to implement.

See above.

John
 
L

Lasse Reichstein Nielsen

John G Harris said:
Alternatively, you could make + an object, a function object. That makes
much more sense as you would expect + to know about numbers and how to
take two numbers and return another number. No mutation of immutable
things here.

If functions are objects, you won't need an object to store the plus
method on, but then you can't really talk about sending messages to
objects (unless you send the "invoke" message to the function object).
Incidentally, you seem to have missed out your [1] text.

Whoops. I removed it deliberatly, but left the [1] in the text.
Every object has a value,

No. Objects *are* values. They have identity, but not necessarily
anything else. They *might* also have properties (values) and methods
(behavior).
The empty object is a perfectly good object.
which now can only be an object. The result is that you have objects
all the way down, for ever.
This disaster can only be rescued by having an object that doesn't have
a value. That becomes the foundation object.

There can be many objects with no values, e.g., anything created using
"new Object()" in Java.

If numbers are objects, there is nothing problematic in that. The
object 42 doesn't have a value. It is the value.

/L
 
J

John G Harris

If functions are objects, you won't need an object to store the plus
method on, but then you can't really talk about sending messages to
objects (unless you send the "invoke" message to the function object).

I'm saying the compiler could translate
op1 + op2

into
+.call(this, op1, op2)

where + is a function object that is internal, hidden from our view (and
'this' is ignored). In fact, that's probably pretty close to what it
does do at present.

Incidentally, you seem to have missed out your [1] text.

Whoops. I removed it deliberatly, but left the [1] in the text.
Every object has a value,

No. Objects *are* values. They have identity, but not necessarily
anything else. They *might* also have properties (values) and methods
(behavior).
The empty object is a perfectly good object.

According to ECMA 262 every object has an internal [[Value]] property,
which we can't remove. So, no object is truly empty.

Every object has a [[Prototype]] property as well.

There can be many objects with no values, e.g., anything created using
"new Object()" in Java.

As above, there are no objects with no values. If everything is an
object then following the [[Value]] properties downwards will take
forever. Likewise for following the [[Prototype]] property.

If numbers are objects, there is nothing problematic in that. The
object 42 doesn't have a value. It is the value.

I don't think you've explained what 'the object 42' means.

Does it mean the literal ?

Or a new Number(42) object ?

If the latter, its [[Value]] is 42. The object contains the value but is
more than the value.

HTH

John
 
D

Dr J R Stockton

In comp.lang.javascript message <55724004-b075-48be-a9f8-bd1d01e2374e@z1
9g2000yqk.googlegroups.com>, Tue, 16 Feb 2010 15:23:12, Jorge
Do you think -as I do- that the Math object is an ugly artifact ?
Well, here's a nice way of getting rid of it :

Number.prototype.sin= function () { return Math.sin(+this); };
Number.prototype.asin= function () { return Math.asin(+this); };
Number.prototype.pow= function (p) { return Math.pow(+this, p); };
Number.prototype.sqrt= function () { return Math.sqrt(+this); };
Number.prototype.rnd= function () { return this*Math.random(); }

Maybe useful for legibility, which means an aid to coding the desired
algorithm. OTOH, is it better than enclosing maths as
with (Math) { ... } // ?

Expected modest loss in performance, which only matters in those
relatively few cases where JavaScript maths is neither inconveniently
slow nor unnecessarily fast.

For those who want legibility and speed, you could write code to
translate "your" maths to/from the standard form.

Your eventual examples need to show how to get, for example, the sine of
an expression; and to warn that 3.sin() is not the same as 3.0.sin().
Those will not be instantly and certainly obvious to all.


How about writing a Reverse Polish Notation interpreter in JavaScript,
to suggest that RPN may one day be included in the language proper? My
LONGCALC.EXE reads, and uses, RPN.


Compare : most methods of the standard Date Object return the date in
milliseconds, which is rarely much use. In my DATE2 object, they
generally return (a reference to) the object itself, so that one can do
D = new DATE2().setXDate(3).setXHours(5)
to go to the third of the current month, time [05:00, 06:00). To get
the milliseconds, just prepend a unary +.
 

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

No members online now.

Forum statistics

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

Latest Threads

Top