Objects comparaison ?

M

Michael Haufe (TNO)

[F]or the sake of argument only:

Interesting.  Can you explain why you prefer these formulations?  I
have no problem at all with using these objects as quasi-namespaces
for related global functionality.
String.fromCharCode    ->  7.fromCharCode()

Okay, except that this functions takes an arbitrary number of
parameters.  How would you handle that?
Date.parse("July 28, 2005") ->  "July 28, 2005".parseDate()

This could work, but what does this have to do String instances?
Should Strings also have parseRegex, parseBoolean, parseJsonObject,
and other similar functions.  If so, why?  What does this have to do
with Strings?
//Number.NaN makes as much sense to me as Number.7
Number.NaN  ->  NaN

Would you also make global Number.NEGATIVE_INFINITY, Number.MAX_VALUE,
and the like?  To what end?  I think there is already far too much in
the global namespace.
Object.create(o)   ->  o.new

This I can almost buy, implemented with code resembling the following:

    Object.prototype.new = function() {
        // create new object and copy over all properties of `this`
    }

But I don't see the harm in the 'Object.create' syntax.  What's the
objection?

At first I replied inline, but with a little more thought I could see
even more questions being raised as a result, so I'll try to take a
step back to give an answer from my perspective as it is a perspective
argument anyway; Hopefully from there it will make more clear what my
intended objections are.

My issue is the organization of the language, and adding all of these
static members doesn't help. I agree with John G Harris's Christmas
Tree statement. A better organization the language should have strived
for is to embrace more of its SmallTalk/Self background than some type
of mixture of half-assed functional. I feel it sits in an awkward
place between the two (plus Java syntax didn't help of course). Sure,
it has first-class functions, but you can't write true functional code
as any ML/Lisp family programmer will tell you. OO is also awkward due
to verbosity and not everything being an object. In comparison to its
relatives, the layout of the inheritance model is pretty slapdash due
to its history. I suspect these things are well known to the community
here and don't need to be stated for the umpteenth time, but maybe I'm
wrong.

So IME, populating Object, Number, and so on with more and more static
members is a perpetuation of design smell. The objects are being
treated like namespaces or generic placeholders for things the awkward
language organization disallowed putting elsewhere (and the backwards
compatibility demon of course). We have Object.create, soon maybe
Function.create and Array.create according to the mailing-list. Do
these not bother you? Why Date.parse instead of new Date? Why not new
Json(...)? Each of these are rhetorical questions in themselves, but
taken as a whole I think the issue is clear.

On to my off-the-cuff code examples: If the language hypothetically
decided to embrace its OO roots and clean up the inheritance model
things may look similar to some of the examples, more specifically the
concept of "specificObjectType.releventMember". What methods go where
and their behavior is less important in relation to having a
consistent means of expressing code. I could ramble on, but this is a
topic better suited to a blog entry or a separate thread* methinks.
Things are getting off-topic enough already. Enough with my droning.

*No doubt someone will jump on my use of the word "thread" here...
 
M

Michael Haufe (TNO)

On Oct 19, 1:21 am, "Michael Haufe (TNO)" wrote:


 >
 > > On Oct 18, 4:05 pm, Scott Sauyet
 >
 > > > John G Harris wrote:
 > > > > Object is a constructor. Its job is to *construct*,
 > > > > not to act like a Christmas tree with shiny
 > > > > ornaments dangling from it.
 >
 > > > So, do you also object to Object.create, Date.parse,
 > > > Number.NaN, String.fromCharCode and everywhere else
 > > > the language associates 'static' properties with
 > > > constructor functions?
 >
 > > Yes
 >
 > More productively, and for the sake of argument only:
 >

Well, since we're already off-topic :)

 > String.fromCharCode    ->  7.fromCharCode()

And neither of those can be usefully passed to map(). :-(

If this was pure OOP, there wouldn't be a separate map function in the
first place of course.

[1,2,3].map(...
this.fromCharCode()
....)

I guess if we really want to get esoteric and proper, we could say
that map doesn't belong to anything but a Functor...
 > Date.parse("July 28, 2005") ->  "July 28, 2005".parseDate()

I would have thought that knowing how to parse a date is the
domain of the Date object.

Or maybe to the Parsing object? Of course I just wanted to express the
idea of _everything_ being of the form foo.bar, though I did so poorly
on the first go.
 > //Number.NaN makes as much sense to me as Number.7
 > Number.NaN  ->  NaN

Or Math.PI?

Indeed
 
A

Antony Scriven

[...]

My issue is the organization of the language, and adding all of these
static members doesn't help. [...]

Gah, I'm probably starting to sound like Thomas Lahn, but
they're not static! I know what you mean though.
A better organization the language should have strived
for is to embrace more of its SmallTalk/Self background
than some type of mixture of half-assed functional.

Hmm, Smalltalk was strongly influenced by Lisp:
http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay_oop_en
I feel it sits in an awkward place between the two (plus
Java syntax didn't help of course).

Only because of its target audience, I believe it was originally
implemented as a Scheme interpreter.
Sure, it has first-class functions, but you can't write
true functional code as any ML/Lisp family programmer
will tell you.

In what sense?
OO is also awkward due to verbosity and not everything
being an object. In comparison to its relatives, the
layout of the inheritance model is pretty slapdash due to
its history.

That's why we now have Object.create().
[...]

So IME, populating Object, Number, and so on with more
and more static members is a perpetuation of design
smell.

They're anything but static. I do get the impression you're
thinking in class-based terms.
The objects are being treated like namespaces or generic
placeholders for things the awkward language organization
disallowed putting elsewhere

There are probably mistakes there as you say. But objects
hold stuff. And functions are first class stuff in
javascript. How could you not have a placeholder holding
stuff in a prototypal language?
(and the backwards
compatibility demon of course).

Yes, that does make things awkward.
We have Object.create, soon maybe Function.create and
Array.create according to the mailing-list. Do these not
bother you?

What's the point of Function.create? (And don't say 'to create
a function'!) The point of Object.create is not so much to
create a new object (you can do that already with {}), but to
set up the prototype chain.
Why Date.parse instead of new Date?

Because 'new' is for class-based languages?
Why not new Json(...)? Each of these are rhetorical
questions in themselves, but taken as a whole I think the
issue is clear.

Sorry, I don't see the issue. Rather I see more of an issue
with having 'new' at all.
On to my off-the-cuff code examples: If the language
hypothetically decided to embrace its OO roots and clean
up the inheritance model things may look similar to some
of the examples, more specifically the concept of
"specificObjectType.releventMember".

Yes, but there's more than one OO (or inheritance) model.
What methods go where and their behavior is less
important in relation to having a consistent means of
expressing code. I could ramble on, but this is a topic
better suited to a blog entry or a separate thread*
methinks. Things are getting off-topic enough already.
Enough with my droning.

*No doubt someone will jump on my use of the word
"thread" here...

Separate threads don't seem to be a feature in
comp.lang.javascript. :) --Antony
 
A

Antony Scriven

On Oct 19, 1:21 am, "Michael Haufe (TNO)" wrote:
Well, since we're already off-topic :)
And neither of those can be usefully passed to map(). :-(

If this was pure OOP, there wouldn't be a separate map function in the
first place of course.

[1,2,3].map(...
this.fromCharCode()
...)

So map() doesn't have take a function parameter now?
I guess if we really want to get esoteric and proper, we
could say that map doesn't belong to anything but
a Functor...

Sure, it's a functor, but we're talking about a specific way
of applying it to an array.
Or maybe to the Parsing object?

Well that would be p = new Parser('date'). You may as well
have a Computation object for all computation.
Of course I just wanted to express the idea of
_everything_ being of the form foo.bar, though I did so
poorly on the first go.

I think part of the problem is that Javascript is largely
functional. It has some sort of organizational notation
using {} (I'm avoiding the term 'object' here) which can be
used to simulate the OO style, but I don't think it's OO in
the usual sense. So I'm not sure that everything should be
foo.bar(). It's not a message-passing language.

I've lost track of the argument now :) --Antony
 
M

Michael Haufe (TNO)

On Oct 20, 12:41 am, "Michael Haufe (TNO)" wrote:
Gah, I'm probably starting to sound like Thomas Lahn, but
they're not static! I know what you mean though.

You're right of course. I should have used "static".

For whatever that is worth in itself. I put more value in the change
of perspective over the lineage.
 > I feel it sits in an awkward place between the two (plus
 > Java syntax didn't help of course).

Only because of its target audience, I believe it was originally
implemented as a Scheme interpreter.

I think I recall /be saying as much
 > Sure, it has first-class functions, but you can't write
 > true functional code as any ML/Lisp family programmer
 > will tell you.

In what sense?

Idiomatically. Abstraction aren't built with function composition,
recursion is rarely used, and this isn't an expression language.
Faking it or trying it will get you punished generally with bad
performance and/or unreadable code.
 > OO is also awkward due to verbosity and not everything
 > being an object. In comparison to its relatives, the
 > layout of the inheritance model is pretty slapdash due to
 > its history.

That's why we now have Object.create().

I don't see how it relates. It doesn't reduce verbosity, it is slower,
and has no effect on the existing organization.
 > So IME, populating Object, Number, and so on with more
 > and more static members is a perpetuation of design
 > smell.

They're anything but static. I do get the impression you're
thinking in class-based terms.

s/static/"static" as mentioned above
 > The objects are being treated like namespaces or generic
 > placeholders for things the awkward language organization
 > disallowed putting elsewhere

There are probably mistakes there as you say. But objects
hold stuff. And functions are first class stuff in
javascript. How could you not have a placeholder holding
stuff in a prototypal language?

Nothing "holds" 'while' or 'if' or 'for' nor do they fall under your
definition of "first class stuff" so yes there are awkward bits. I
think you misunderstand though; I am not implying that there should be
objects which have nothing related to them (they would have no reason
to exist then). It is an organization choice that could be made
better.
 > We have Object.create, soon maybe Function.create and
 > Array.create according to the mailing-list. Do these not
 > bother you?

What's the point of Function.create? (And don't say 'to create
a function'!)

To create a function: said:
The point of Object.create is not so much to
create a new object (you can do that already with {}), but to
set up the prototype chain.

I think it is more about the meta properties than the prototype.
Constructors did just fine.
 > Why Date.parse instead of new Date?

Because 'new' is for class-based languages?

 > Why not new Json(...)? Each of these are rhetorical
 > questions in themselves, but taken as a whole I think the
 > issue is clear.

Sorry, I don't see the issue. Rather I see more of an issue
with having 'new' at all.

The lack of consistency in creating objects being the issue.
 > On to my off-the-cuff code examples: If the language
 > hypothetically decided to embrace its OO roots and clean
 > up the inheritance model things may look similar to some
 > of the examples, more specifically the concept of
 > "specificObjectType.releventMember".

Yes, but there's more than one OO (or inheritance) model.

Prototypical of course.
Separate threads don't seem to be a feature in
comp.lang.javascript. :)

Maybe I'll ask Google Groups to implement them next to the Spam link...
 
M

Michael Haufe (TNO)

So map() doesn't have take a function parameter now?

I was lazy so I used "..." to leave out the obvious
Well that would be p = new Parser('date'). You may as well
have a Computation object for all computation.

Like Monad or Arrow? ;)

I don't know if I'd laugh or cry.
I think part of the problem is that Javascript is largely
functional. It has some sort of organizational notation
using {} (I'm avoiding the term 'object' here) which can be
used to simulate the OO style, but I don't think it's OO in
the usual sense. So I'm not sure that everything should be
foo.bar(). It's not a message-passing language.

If we could move towards "everything is a(n) [...]" that'd be fine
with me
 
J

John G Harris

So is your concern only with Object as the root of the object
hierarchy, or does your objection apply to all constructor functions?
Date.parse doesn't accept a Date, only a String. String.fromCharCode
accepts a number of integers.

Would you be happy if it was Number.parse that turned a string into a
Date? I'd say it would be no more inappropriate. Remember, Thomas's
function was not restricted to objects.

I use this pattern extensively, and wonder if you have an objection to
it, and if so, why:

var MyConstructor = function() { /* ... */ };
MyConstructor.prototype = { /* ... */ }
MyConstructor.staticFunc1 = function() { /* ... */ };

Well, yes, I don't think it's nice. Writing the code to create an object
is one job; writing quasi-global functions for using these objects is
another job. These jobs might be done at different times, or by
different people.

I can understand you wanting to use the constructor, but have you ever
thought of using a separate object to hold things that are not inside
the objects but are related to them? (In C++ it would be a namespace).

[Aside to others: 'static' is a bit of history from C++, maybe via Java.
It doesn't have the obvious meaning.]

I don't generally think of these static functions as operating
specifically on single instances that were constructed from the
function, so I don't think of it as an issue. But just out of
curiosity, how would you accomplish this multiple constructor
scenario?

I think you've misunderstood me. I'm talking about a bunch of objects,
all of the same kind. Some have been created by one constructor, some by
another constructor.

For instance, by

new Thing(2057, "left-handed sproggle")
which creates a new thing object holding the given values;

new ThingClone(t)
where 't' must be another thing object
which creates a new object with the same values as in t.
(In C++ ThingClone would be called a copy constructor.)

Now, which of these constructors do you hang the quasi-global functions
from?


John
 
A

Antony Scriven

[...]

var MyConstructor = function() { /* ... */ };
MyConstructor.prototype = { /* ... */ }
MyConstructor.staticFunc1 = function() { /* ... */ };

Well, yes, I don't think it's nice. Writing the code to
create an object is one job; writing quasi-global
functions for using these objects is another job. These
jobs might be done at different times, or by different
people.

I can understand you wanting to use the constructor, but
have you ever thought of using a separate object to hold
things that are not inside the objects but are related to
them? (In C++ it would be a namespace).

He did. MyConstructor is one object. MyConstructor.prototype
is another.
[...]

I think you've misunderstood me. I'm talking about
a bunch of objects, all of the same kind. Some have been
created by one constructor, some by another constructor.

For instance, by

new Thing(2057, "left-handed sproggle")
which creates a new thing object holding the given values;

new ThingClone(t)
where 't' must be another thing object
which creates a new object with the same values as in t.
(In C++ ThingClone would be called a copy constructor.)

Now, which of these constructors do you hang the
quasi-global functions from?

var t = Thing.make(2057, "left-handed sproggle");
var u = Thing.makeclone(t);

They're static factory methods if you're looking at this
from a the perspective of a class-based language. --Antony
 
T

Thomas 'PointedEars' Lahn

John said:
You really do need to learn to provide a reasoned explanation instead of
abusive hot air.

You appear to have a serious reading problem.
<snip>

What a bloody awful thing to do.

You definitely have a serious reading problem, and one with quoting, too.
Go away.


PointedEars
 
A

Antony Scriven

[...]

For instance, by

new Thing(2057, "left-handed sproggle")
which creates a new thing object holding the given values;

new ThingClone(t)
where 't' must be another thing object
which creates a new object with the same values as in t.
(In C++ ThingClone would be called a copy constructor.)

Now, which of these constructors do you hang the
quasi-global functions from?

var t = Thing.make(2057, "left-handed sproggle");
var u = Thing.makeclone(t);

[...]

That said, t.clone() would make more sense to me for this
case. --Antony
 
A

Antony Scriven

John G Harris wrote:

[...]
Object.prototype.equals = function(obj1, obj2) {
...
}; <snip>

What a bloody awful thing to do. [Reason for it being a
bloody awful thing silently snipped. --Antony]

You definitely have a serious reading problem, and one
with quoting, too. Go away.

You seem to have snipped the rest of what John said without
addressing his argument nor indicating that you've edited
his text. --Antony
 
S

Scott Sauyet

John said:
Would you be happy if it was Number.parse that turned a string into a
Date? I'd say it would be no more inappropriate.

I'd say that was extremely inappropriate. A function that creates
Date objects from some other structure sounds like something that
should be handled by Date. The fact that Date is a constructor as
well as a holder for this factory function is simply a byproduct of
the fact that functions *are* objects.

Perhaps you would be happier with a construct like:

var MyDate = {
create: function(year, month, day /*, ... */) { /* ... */},
parse: function(stringRep) {/* ... */},
now: function() {/* ... */}
/*, ... */
};

While I have no problem with that structure, I quite like using
constructor functions for this purpose. I don't feel as though I'm
breaking any rules or skirting around the language designs in doing
so. Rather, I feel as though I'm using some of its better features.

Remember, Thomas's function was not restricted to objects.

It's a dynamic language. You don't get to control what is passed to
your public functions. So you better be willing and able to handle
data of types other than what you would prefer. Moreover, I assumed
he was using Object as the root of the Object hierarchy, with an eye
towards checking if all the properties of the two parameters are
equal. So the fact that you could use this with, say, two RegExp
objects, or a Date and an Array is not necessarily a problem. Thomas
did not try to actually present such a function. That might not be so
simple. But if I were to write such a function meant to be included
as part of the language, the Object constructor is by far the best
place to put it.


Well, yes, I don't think it's nice. Writing the code to create an object
is one job; writing quasi-global functions for using these objects is
another job. These jobs might be done at different times, or by
different people.

I can understand you wanting to use the constructor, but have you ever
thought of using a separate object to hold things that are not inside
the objects but are related to them? (In C++ it would be a namespace).

Yes, and at times I do use a separate object. But I haven't really
seen any argument about why it's wrong to use the constructor object
for this purpose, only your distaste for doing so. Can you say *why*
you object? (And no, saying that these are two different jobs does
not suffice. Any object with more than one function attached does
more than one job.)

[Aside to others: 'static' is a bit of history from C++, maybe via Java.
It doesn't have the obvious meaning.]

Yes, perhaps we shouldn't be using it here, if it doesn't mean much to
others. In, say, Java, "static" members are ones that apply at a
class level, and not to individual instances. A counter of instances
created or a next-id generator are classic examples. It's a pretty
straightforward analog to properties that are associated with the
constructor versus those associated with the prototype.

I think you've misunderstood me. I'm talking about a bunch of objects,
all of the same kind. Some have been created by one constructor, some by
another constructor.

So what makes them all of the same kind? Do they still share the same
prototype chain? If not, I would argue against calling them the same
kind.

For instance, by

   new Thing(2057, "left-handed sproggle")
which creates a new thing object holding the given values;

   new ThingClone(t)
where 't' must be another thing object
which creates a new object with the same values as in t.
(In C++ ThingClone would be called a copy constructor.)

Now, which of these constructors do you hang the quasi-global functions
from?

Well, first of all, I wouldn't do it that way. Depending on the
implementation, I would either attach a 0-parameter `clone` function
to the prototype of Thing, or attach to the Thing constructor a
`clone` function that accepted a Thing object. In either case, the
result would be an object constructed with the Thing constructor.

Do you really have use-cases that work this way?


I think the problem is a disagreement in mapping. Of course the
language features do not map precisely, but if we were to try to map
Javascript to Java, I think you would map JS constructor functions to
Java constructors. (Do I have that right?) I would map JS
constructor functions to Java classes. They define the data type, and
own prototypes, which contain the common features. Of course they
also serve as the only constructors of these objects, but that to me
is secondary. If I'm right about this disagreement, do you have a
mapping for Java classes in JS?

-- Scott
 
J

John G Harris

var t = Thing.make(2057, "left-handed sproggle");
var u = Thing.makeclone(t);

They're static factory methods if you're looking at this
from a the perspective of a class-based language. --Antony

Alternatively, in ECMAScript they don't need to be factory methods; they
can be constructors :

var t = new Thing.make(2057, "left-handed sproggle");
var u = new Thing.clone(t);

Add some quasi-global, 'static', methods to Thing and you have the
analogue of a C++/Java class definition - the place where everything
about a class is declared. (Scott shows something similar.) Now you're
cooking with gas!

John
 
J

John G Harris

I'd say that was extremely inappropriate. A function that creates
Date objects from some other structure sounds like something that
should be handled by Date. The fact that Date is a constructor as
well as a holder for this factory function is simply a byproduct of
the fact that functions *are* objects.

Perhaps you would be happier with a construct like:

var MyDate = {
create: function(year, month, day /*, ... */) { /* ... */},
parse: function(stringRep) {/* ... */},
now: function() {/* ... */}
/*, ... */
};

While I have no problem with that structure, I quite like using
constructor functions for this purpose. I don't feel as though I'm
breaking any rules or skirting around the language designs in doing
so. Rather, I feel as though I'm using some of its better features.

You're certainly not breaking any rules, nor are you skirting round the
language design.

On the other hand, if you are doing the constructor and those wallies
down the corridor are doing the helper functions, are you really sure
they aren't going to mess up your tested constructor code when they come
to attach functions to it?

If you're really sure, then no problem.

It's a dynamic language. You don't get to control what is passed to
your public functions. So you better be willing and able to handle
data of types other than what you would prefer. Moreover, I assumed
he was using Object as the root of the Object hierarchy, with an eye
towards checking if all the properties of the two parameters are
equal. So the fact that you could use this with, say, two RegExp
objects, or a Date and an Array is not necessarily a problem. Thomas
did not try to actually present such a function. That might not be so
simple. But if I were to write such a function meant to be included
as part of the language, the Object constructor is by far the best
place to put it.

Remember that Thomas's function tests if the two parameters are both
objects, and if not does :
return (obj1 === obj2);

There could be a program that uses Object.equals to compare numbers and
strings, and nothing else. That's why I say Object is inappropriate.

As for getting to control what is passed, I belong to the school that
says that it's the callers fault if he ignores a function's
specification. Asking for the colour of today's date, for instance, is
asking for trouble, (and a swift kick up the arse if it was deliberate).

Yes, and at times I do use a separate object. But I haven't really
seen any argument about why it's wrong to use the constructor object
for this purpose, only your distaste for doing so. Can you say *why*
you object? (And no, saying that these are two different jobs does
not suffice. Any object with more than one function attached does
more than one job.)

Separation of concerns. See above.

[Aside to others: 'static' is a bit of history from C++, maybe via Java.
It doesn't have the obvious meaning.]

Yes, perhaps we shouldn't be using it here, if it doesn't mean much to
others. In, say, Java, "static" members are ones that apply at a
class level, and not to individual instances. A counter of instances
created or a next-id generator are classic examples. It's a pretty
straightforward analog to properties that are associated with the
constructor versus those associated with the prototype.

I think you've misunderstood me. I'm talking about a bunch of objects,
all of the same kind. Some have been created by one constructor, some by
another constructor.

So what makes them all of the same kind? Do they still share the same
prototype chain?

Of course.

If not, I would argue against calling them the same
kind.

And I'd say the same.

Well, first of all, I wouldn't do it that way. Depending on the
implementation, I would either attach a 0-parameter `clone` function
to the prototype of Thing, or attach to the Thing constructor a
`clone` function that accepted a Thing object. In either case, the
result would be an object constructed with the Thing constructor.

Do you really have use-cases that work this way?

Look at some C++ or Java programs. You'll find many cases of multiple
constructors.

I think the problem is a disagreement in mapping. Of course the
language features do not map precisely, but if we were to try to map
Javascript to Java, I think you would map JS constructor functions to
Java constructors. (Do I have that right?) I would map JS
constructor functions to Java classes. They define the data type, and
own prototypes, which contain the common features. Of course they
also serve as the only constructors of these objects, but that to me
is secondary. If I'm right about this disagreement, do you have a
mapping for Java classes in JS?

It's not so much a disagreement, more a case of in ECMAScript there
always seems to be several ways of doing the same thing. It's important
not to get too fixated on one way, or condemn other ways outright.

What is bad is messy work or muddled thinking. Trying to make the code
look too much like another language, rather than aiming for the same end
result, is always a bad sign.

John
 
A

Andreas Bergmaier

John said:
Alternatively, in ECMAScript they don't need to be factory methods; they
can be constructors :

var t = new Thing.make(2057, "left-handed sproggle");
var u = new Thing.clone(t);

Why should a clone /method/ be a constructor? I'd prefer this:

var t = new Thing(x, y, z);
or maybe
var t = new Thing.maker(x, y, z);
and then
var u = t.clone(); // prototyped, or not to get "private" attributes
or
var u = Thing.clone(t);

so that both t and u are instances of Thing (or Thing.maker).

Andreas
 
J

John G Harris

John G Harris schrieb:


Why should a clone /method/ be a constructor? I'd prefer this:
<snip>

Your style preference is your decision, of course, but being consistent
can make life easier. For instance, Java's String class has 11
constructors. One is a clone function, another is effectively a clone
function. Why should these two be written and documented in another part
of the program?

Regarding 'method' : all functions are properties of some object, and
hence are methods of some object, even if it's only the Global Object.

John
 
S

Scott Sauyet

Michael Haufe (TNO) said:
Scott Sauyet wrote:
[ ... ] But I don't see the harm in the 'Object.create' syntax.  
What's the objection?
[ ... ]

My issue is the organization of the language, and adding all of these
static members doesn't help. I agree with John G Harris's Christmas
Tree statement. A better organization the language should have strived
for is to embrace more of its SmallTalk/Self background than some type
of mixture of half-assed functional.

It's the functional side of the language which gives me the me the
most pleasure. Yes, it's half-assed, but that's still better than not
being functional at all. So I guess I prefer the Scheme side of the
equation.
I feel it sits in an awkward
place between the two (plus Java syntax didn't help of course). Sure,
it has first-class functions, but you can't write true functional code
as any ML/Lisp family programmer will tell you. OO is also awkward due
to verbosity and not everything being an object. In comparison to its
relatives, the layout of the inheritance model is pretty slapdash due
to its history. I suspect these things are well known to the community
here and don't need to be stated for the umpteenth time, but maybe I'm
wrong.

I have a significantly different take on this. Yes, there are things
that are somewhat off-kilter in the language, but I treat them mostly
as quirks. I'm pretty happy with the set of feature available, and
really look forward to the new features proposed for ES.next
(especially the mandatory tail-call optimization.)

So IME, populating Object, Number, and so on with more and more static
members is a perpetuation of design smell. The objects are being
treated like namespaces or generic placeholders for things the awkward
language organization disallowed putting elsewhere (and the backwards
compatibility demon of course).

Maybe I'm just too complacent. Maybe I've just been working with
Javascript too long. But treating one object as both a constructor
function and a namespace seems quite sensible to me. Were the
language more like Java, it would be classes that held both the static
functions and the constructors. JS, of course, doesn't offer any
clear path to multiple constructors, so there simply doesn't seem to
be a need for another structure to fill this role. The constructor
function works well.
We have Object.create, soon maybe
Function.create and Array.create according to the mailing-list. Do
these not bother you? Why Date.parse instead of new Date? Why not new
Json(...)? Each of these are rhetorical questions in themselves, but
taken as a whole I think the issue is clear. [ ... ]

These don't bother me. I'd rather keep the language as far from Java
as possible. I don't want classes; I really like the prototypal
inheritance. I'm happy that a single constructor function and its
prototype form the main means of type definition. If that means that
the most likely places to attach 'static' functions is those
constructors, so be it.

-- Scott
 
T

Thomas 'PointedEars' Lahn

Andreas said:
Why should a clone /method/ be a constructor? I'd prefer this:

var t = new Thing(x, y, z);
or maybe
var t = new Thing.maker(x, y, z);
and then
var u = t.clone(); // prototyped, or not to get "private" attributes

ACK, but you mean _properties_, not attributes.
or
var u = Thing.clone(t);

so that both t and u are instances of Thing (or Thing.maker).

var u = new Thing(t);

is what I allowed in my experimental Map implementation, which calls
putAll() to construct a Map instance with exactly the same key-value pairs
as the original. Therefore, the definition of the clone() method of Map
instances became rather simple:

/**
* Returns a shallow copy of this map
*
* @return Map
* @public
*/
this.clone = function() {
return new this.constructor(this);
};

(Which actually does not access any private-local variables, so should be
defined as a prototype method.)

<http://pointedears.de/websvn/filedetails.php?repname=JSX&path=/trunk/map.js>


PointedEars
 

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
473,763
Messages
2,569,562
Members
45,038
Latest member
OrderProperKetocapsules

Latest Threads

Top