Current JSON Proposal in ES4

D

dhtmlkitchen

JSON
We all know what it is.

In ECMAScript 4, there's a JSON proposal:

Object.prototype.toJSONString
String.prototype.parseJSON


The current proposal, String.prototype.parseJSON, returns an object.
This is very poor design. It's worse than Date.parse(s), which returns
a Number (not a Date).

The current proposal, Object.prototype.toJSONString, complicates
objects with responsibility that they should not necessarily have. It
will be easy to misuse. It will conflate Object.prototype with
implementation details possibly leaking into places they shouldn't.
Instead of keeping reduced access, it maximizes access. It does not
allow the functionality to be tested and debugged independently.

If these features go in the language, implementations and library
authors will be required to handle this method for all objects, of any
type, forever. The change will be permanent and unretractable.

This feature is not critical; it can be added at any time. The flip
side to that is that once added, it cannot be removed. ever.
Alternatives

1. A built in JSON object

A built in JSON object would keep the JSON serialization/parsing
independent. It will be easy to learn, easy to extend, easy to read
and maintain code that uses it, and it will fulfill the requirements.
It won't complicate Object.prototype.

JSON.parseFromString( s );
JSON.toJSONString( jsonObject, pretty );


2. A JSON Interface

A JSON interface can be implemented to allow a class to have the
JSON Methods as instance methods.

function parseFromString( s, pretty ) : <T>
function toJSONString( );


An JSON interface could instead be simply a tagging interface.
If the object supports the JSON interface, it could be used with a
JSON static JSON.parseFromString( s, type );, where type is something
like Map.

Test this out with three different types, say: Object, Map, and
Array.

If JSON is in the langauge, there will need to be some sort of
JSONError Error object.
 
R

Richard Cornford

JSON
We all know what it is.

A subset of javascript's Object/Array literal notation used for data
representation/exchange.
In ECMAScript 4, there's a JSON proposal:

Object.prototype.toJSONString
String.prototype.parseJSON


The current proposal, String.prototype.parseJSON, returns an
object. This is very poor design. It's worse than
Date.parse(s), which returns a Number (not a Date).

Why, given that part of the point of JSON is that it can be directly
translated into object structures in jvascrtip?
The current proposal, Object.prototype.toJSONString,
complicates objects with responsibility that they
should not necessarily have.

Why shouldn't an object have a specialised serialisation method?
It will be easy to misuse.

An example of this "misuse"?
It will conflate Object.prototype with implementation
details possibly leaking into places they shouldn't.
Instead of keeping reduced access, it maximizes access.
It does not allow the functionality to be tested and
debugged independently.

If these features go in the language, implementations and
library authors will be required to handle this method
for all objects, of any type, forever. The change will
be permanent and unretractable.

This feature is not critical; it can be added at any time.
The flip side to that is that once added, it cannot be
removed. ever.

There are many assertions here but not one substantial argument to back
any of them up. Between ECMA 262 2nd edition and 3rd edition the object
prototype gained hasOwnProperty, propertyIsEnumerable and isPrototypeOf
methods with no negative impact. Adding methods to the object prototype
does not necessarily have any impact on anything else at all.
Alternatives

1. A built in JSON object

Because JSON translates directly into structures of javascript
objects/arrays it makes no sense to attempt to create a specific JSON
object.

If JSON is in the langauge, there will need to be
some sort of JSONError Error object.

A JAON parsing error seems appropriate, though javascript's errors need
a great deal of additional work before they become that usable.

Richard.
 
D

dhtmlkitchen

A subset of javascript's Object/Array literal notation used for data
representation/exchange.


Why, given that part of the point of JSON is that it can be directly
translated into object structures in jvascrtip?
Integer.parseInt <-- what should this return?
Date.parse <-- what should this return?

now,
String.parseJSON <-- should return what, a String?

Why shouldn't an object have a specialised serialisation method?
Why should it?

If it needs one, it can get it independently. It could define it's own
method for serialization. Not all objects need this.
An example of this "misuse"?
HTMLInputElement.prototype.toJSONString = getPWD;

or the widget example below.

Any of the misuses of for-in loop, or closures would seem not as bad.
There are many assertions here but not one substantial argument to back
any of them up. Between ECMA 262 2nd edition and 3rd edition the object
prototype gained hasOwnProperty, propertyIsEnumerable and isPrototypeOf
methods with no negative impact. Adding methods to the object prototype
does not necessarily have any impact on anything else at all.

propertyIsEnumerable attempts, but fails in addressing the problem of
determining if a property is enumerable. It is broken, as defined by
ECMA-262. The JScript bug eliminates any possibility of this method
being suitable for cross-browser use.

Objects need to deal with enumeration; they're stuck with this
responsibility. This is is a problem.

isPrototypeOf is useless/harmless. Can't be removed, though.

toJSONString would not be so benign. It's almost as bad is Object
enumeration. Or maybe worse. It means that every object is, by
default, not just a data structure, but a data structure that also
supports a specialized (or default) serialization. How in any way, is
it justified?

Maybe 2% of all objects will need serialization at most.

for example:

x.toJSONString();

if x is an instance of

function Widget() {
_name : "widget_" + widget.instances.length;
}

Well, then you have to filter out the _name property in your serialize
method.

Because JSON translates directly into structures of javascript
objects/arrays it makes no sense to attempt to create a specific JSON
object.
JSON is a subset of JavaScript

JSON translates into JS structures.

JS Structures do not translate to JSON.

By design of the language, JS Objects are structures. That is what
Data Structures are for.

xxx = Function();
xxx.name = "foo";

bork = {
p : xxx
,s : "<script src='http://hack.us/"></script>"
,hasOwnProperty : document.createElement
};

It is not justified in ES3.

Adding serialization capabilities to every object creates unnecessary
complications. Each type of object has to deal with this.

How would you serialize a Callable, a subclassed string, an
HTMLInputElement?

How is any of the above justified?
 
T

Thomas 'PointedEars' Lahn

In ECMAScript 4, there's a JSON proposal:

Object.prototype.toJSONString
String.prototype.parseJSON

Good idea.
The current proposal, String.prototype.parseJSON, returns an object.
This is very poor design.

IBTD. As JSON is a subset of Object/Array literal notation, I don't see a
reason why the result should *not* be an object.
It's worse than Date.parse(s), which returns a Number (not a Date).

Date.parse(s) is more flexible than it would be if it returned a Date object
reference. If the number bothers you, you are free to use `new Date(s)'
instead or use the return value of Date.parse(s) as argument for the
constructor.
The current proposal, Object.prototype.toJSONString, complicates
objects with responsibility that they should not necessarily have. It
will be easy to misuse. It will conflate Object.prototype with
implementation details possibly leaking into places they shouldn't.

Why would that be? Those will be built-in methods then, and most certainly
they will have the DontEnum attribute.
Instead of keeping reduced access, it maximizes access.

More important is that such methods would finally provide efficient
implementation-independent means.
It does not allow the functionality to be tested and debugged independently.

Did you care to debug toString(), toValue() aso. to date?
[...]
An JSON interface could instead be simply a tagging interface.
If the object supports the JSON interface, it could be used with a
JSON static JSON.parseFromString( s, type );, where type is something
like Map.

Test this out with three different types, say: Object, Map, and
Array.

Please forgive my ignorance, what would Map be?
If JSON is in the langauge, there will need to be some sort of
JSONError Error object.

That would be useful, but not necessary.


PointedEars
 
D

dhtmlkitchen

Good idea.


IBTD. As JSON is a subset of Object/Array literal notation, I don't see a
reason why the result should *not* be an object.
Objects are used for collections. There are no other collection types
in ES3.

Objects are used for other things than collections, most of the time.

The conflation of Object and Hashtable causes problems in ES. Adding
toJSONString further complicates Objects with more responsibility.

Date.parse(s) is more flexible than it would be if it returned a Date object
reference. If the number bothers you, you are free to use `new Date(s)'
instead or use the return value of Date.parse(s) as argument for the
constructor.
The return type is incorrect. Even in Java's Date object (which has
it's problems) Date.parse returns a Date (normal). The problem is that
you can't parse localized dates based on a string. It's impossible.
Why would that be? Those will be built-in methods then, and most certainly
they will have the DontEnum attribute.
W/A JSON Object, You could add it yourself w/only a few lines of code:

unit ThomasJSON {
internal package ThomasJSON {
Object.prototype.toJSONString = function () { return
JSON.toJSONString(this) };
Object.prototype.propertyIsEnumerable("toJSONString", false);
}
}

In your code:

use unit ThomasJSON "http://example.com";
More important is that such methods would finally provide efficient
implementation-independent means.


Did you care to debug toString(), toValue() aso. to date?
What is aso?

valueOf should produce testable, consistent results on Date objects

Date.prototype.toString providing a formatting dependency is a
problem. It is not localized.

toDateString and toTimeString should be on a DateFormatter class.

toString should be for diagnostic info.
[...]
An JSON interface could instead be simply a tagging interface.
If the object supports the JSON interface, it could be used with a
JSON static JSON.parseFromString( s, type );, where type is something
like Map.
Test this out with three different types, say: Object, Map, and
Array.

Please forgive my ignorance, what would Map be?

If JSON is in the langauge, there will need to be some sort of
JSONError Error object.

That would be useful, but not necessary.
Depends what 'necessary' means. A lot of necessary things
(collections) are missing in ES3, yet we manage.

Constructor's based on Error (subclass) in ES3 doesn't really work
that well.
 
R

Richard Cornford

Integer.parseInt <-- what should this return?

No such construct exists in javascript as there is no Integer object
and - parseInt - is a global function.
Date.parse <-- what should this return?

A 'static' method of the Date constructor might be expected to return
something that was date related.
now,
String.parseJSON <-- should return what, a String?

Wasn't it - String.prototype.parseJSON - that you were objecting to? An
instance method of String object might be executed to turn that string
into anything. As JSON is a structure consisting of and object or array
with optional nested descendants then that is the likely result.
Why should it?

Precedence would be a good enough reason, as JavaScript(tm) already
has - toSource - method on objects. All this adds is another form of
serialisation, and one that has obvious practical applications.
If it needs one, it can get it independently.

Maybe, but not a native code (so relatively fast) method.
It could define it's own
method for serialization. Not all objects need this.

Much as objects don't need - toSource - but don't suffer for having it.
HTMLInputElement.prototype.toJSONString = getPWD;

There is plenty of scope for doing stupid things with the language as it
is.
or the widget example below.

Any of the misuses of for-in loop, or closures
would seem not as bad.

Which misuses?
propertyIsEnumerable attempts, but fails in addressing the
problem of determining if a property is enumerable. It is
broken, as defined by ECMA-262.

You have said that before, but still have not posted any demonstration
of this supposed brokenness.
The JScript bug eliminates any possibility of this method
being suitable for cross-browser use.

Which JScript bug? The one where - dontEnum - attributes are inherited
through the prototype chain when they should not be? The fact that the
properties should be enumerable when they are not doesn't modify the
effectiveness of the - propertyIsEnumerable - when it just reports false
for properties that are not innumerable. The reality is what the method
is supposed to report.
Objects need to deal with enumeration;
they're stuck with this
responsibility. This is is a problem.

It is not a problem. It has never been feasible to directly use
javascript objects as storage faculties for mapping arbitrary string
keys to values. The 'safe' set of possible keys in such a context don't
suffer from enumeration issues even in IE browsers.
isPrototypeOf is useless/harmless. Can't be removed,
though.

As useless/irrelevant as - instanceof -.
toJSONString would not be so benign.

Why not, it would do no harm if not used, and if used then there would
presumably be some reason for using it.
It's almost as bad is Object enumeration.

What is "bad" about object enumeration?
Or maybe worse. It means that every object is, by
default, not just a data structure, but a data structure that
also supports a specialized (or default) serialization.

Which is already the reality for JavaScript(tm) and that doesn't seem to
have resulted in any problems.
How in any way, is it justified?

Expedience, in the face of a growing use of JSON as a data exchange
medium, and particularly for transmission between HTTP clients and
servers.
Maybe 2% of all objects will need serialization at most.

Maybe, maybe not. What of it, I don't thing I have ever used
propertyIsEnumerable in production code but no objects have suffered for
having that unused method?
for example:

x.toJSONString();

if x is an instance of

function Widget() {
_name : "widget_" + widget.instances.length;
}

Well, then you have to filter out the _name property in your
serialize method.

Why? What is it doing there if you don't want it included in the
serialisation, or if you don't want it why use the prototype
toJSONString method? You are the one doing the programming so program
the system to be what you want it to be.
JSON is a subset of JavaScript

Yes, a restriction of the nature of property name declarations in the
object literal strings and the types of values that may be assigned to
properties.
JSON translates into JS structures.

Which is what we are doing, taking a JSON string and getting a
javascript object.
JS Structures do not translate to JSON.

They can (or the whole thing would be a non-starter). All you are saying
is that objects can be created that will not translate well. And they
can, but that does not mean that rational programmers will create such
objects.
By design of the language, JS Objects are structures.
That is what Data Structures are for.

xxx = Function();
xxx.name = "foo";

bork = {
p : xxx
,s : "<script src='http://hack.us/"></script>"
,hasOwnProperty : document.createElement
};

What is your point here?
It is not justified in ES3.

Adding serialization capabilities to every object creates
unnecessary complications. Each type of object has to deal
with this.

More like the serialisation process has to be able to deal with (in some
predetermined manner) all possible javascript objects. But that is just
a mater of specification.
How would you serialize a Callable, a subclassed string,
an HTMLInputElement?

HTMLInputElement are not required to have prototype chins or inherit
form Object.protoype so they are irrelevant in the general case. Other
objects have properties with attributes and values regardless of their
'type'.
How is any of the above justified?
<snip>

How is any of what justified? The proposed methods are an expedient or
harmless addition to the group of methods already on the pertinent
prototypes.

Where is your downside for this? All you have said above is that handing
these extra methods to a fool with give them extra opportunities to
shoot themselves in the foot. But so what, they were likely to shoot
themselves in the foot one way or another even without those methods?

They are a much better idea than many of the proposals I have seen to
date. At lest they will do absolutely nothing to break
back-compatibility in the language and they will be extremely useful to
a great many web application developers.

Richard.
 
P

Peter Michaux

Objects are used for collections. There are no other collection types
in ES3.

Objects are used for other things than collections, most of the time.

The conflation of Object and Hashtable causes problems in ES.

In all completely object-oriented languages, like JavaScript, isn't it
necessary that hashes are objects?


Adding
toJSONString further complicates Objects with more responsibility.

If the line of purity has already been crossed, and objects have more
responsibilities than they should, what exactly is _so_ offensive with
one more? That is meant as a genuine question. Will the existence of
the toJSONString property make day-to-day programming with JavaScript
more difficult or different than it is now?


unit ThomasJSON {

Is "unit" a new keyword for ES4?


Map<T,T> is a data structure. It's in ES4. Long overdue.

Is the "<T,T>" optional for those that don't want to use types?

We are really headed towards Java, aren't we? The sad thing is some
poor JavaScript programmers, who don't want to program in Java, are
going to be told to program the Java way once ES4 is available.



Peter
 
R

Richard Cornford

Peter said:
On Oct 22, 3:09 pm, "(e-mail address removed)" wrote:

Is "unit" a new keyword for ES4?

And say goodbye to any hope of back-compatibility with current versions
if it is, as up until now "unit" had been a valid Identifier, and one I
use quite often as I use JS object reprehensions of commercial
buildings, which are sub-divided into units.

We are going to end up with another MIME type hack here.
Is the "<T,T>" optional for those that don't want to
use types?

We are really headed towards Java, aren't we?

Unfortunately it has looked that way for some time. Java already exists
so I don't see the point in trying to create another. And it is a near
certainty that the end result actually will be the inferior Java that
javascript is already often mistakenly perceived as being.
The sad thing is some poor JavaScript programmers, who
don't want to program in Java, are going to be told to
program the Java way once ES4 is available.

What makes you think ES4 will offer the choice?

Richard.
 
D

dhtmlkitchen

In all completely object-oriented languages, like JavaScript, isn't it
necessary that hashes are objects?
A HashMap is an Object, an Object is not a HashMap. An object might be
a Menu. A Menu is not a HashMap. Too much responsibility for a Menu.
It violates most general programming principles like cohesion, SRP. It
is a problem with the ES3-.

If the line of purity has already been crossed, and objects have more
responsibilities than they should, what exactly is _so_ offensive with
one more? That is meant as a genuine question. Will the existence of
the toJSONString property make day-to-day programming with JavaScript
more difficult or different than it is now?
Getting away from object as a hashtable is the right direction.

Is "unit" a new keyword for ES4?


Is the "<T,T>" optional for those that don't want to use types?

Not optional, however,

<Object,Object>

- or -

We are really headed towards Java, aren't we? The sad thing is some
poor JavaScript programmers, who don't want to program in Java, are
going to be told to program the Java way once ES4 is available.
That is false.

ES4 is backwards compatible.
 
P

Peter Michaux

And say goodbye to any hope of back-compatibility with current versions
if it is, as up until now "unit" had been a valid Identifier, and one I
use quite often as I use JS object reprehensions of commercial
buildings, which are sub-divided into units.

We are going to end up with another MIME type hack here.




Unfortunately it has looked that way for some time. Java already exists
so I don't see the point in trying to create another. And it is a near
certainty that the end result actually will be the inferior Java that
javascript is already often mistakenly perceived as being.


What makes you think ES4 will offer the choice?


Today a new ES4 document

<URL: http://www.ecmascript.org/es4/spec/overview.pdf>

was announced in the following post

http://www.nabble.com/ES4-overview-paper-released-p13352309.html

The first page of the document says

"ES4 is compatible with ES3 and adds..."

I suppose that adding reserved words to the language is not quite an
exception to this statement but ES3 code won't necessarily run as ES4
code if there are new keywords in the language. The Perl and PHP
programs would be smug when observing a situation like this with their
@foo and $bar identifiers.

Peter
 
P

Peter Michaux

And say goodbye to any hope of back-compatibility with current versions
if it is, as up until now "unit" had been a valid Identifier, and one I
use quite often as I use JS object reprehensions of commercial
buildings, which are sub-divided into units.

We are going to end up with another MIME type hack here.




Unfortunately it has looked that way for some time. Java already exists
so I don't see the point in trying to create another. And it is a near
certainty that the end result actually will be the inferior Java that
javascript is already often mistakenly perceived as being.


What makes you think ES4 will offer the choice?


Today a new ES4 document

<URL: http://www.ecmascript.org/es4/spec/overview.pdf>

was announced in the following post

http://www.nabble.com/ES4-overview-paper-released-p13352309.html

The first page of the document says

"ES4 is compatible with ES3 and adds..."

I suppose that adding reserved words to the language is not quite an
exception to this statement but ES3 code won't necessarily run as ES4
code if there are new keywords in the language. The Perl and PHP
programs would be smug when observing a situation like this with their
@foo and $bar identifiers.

Peter
 
D

dhtmlkitchen

No such construct exists in javascript as there is no Integer object
and - parseInt - is a global function.
The example was taken from Java, to illustrate the concept that
XXX.parse is usually expected to return an XXX.

parseInt should be a Number function, not global.parseInt.

Number.parseInt

BTW, global is accessible in ES4.

A 'static' method of the Date constructor might be expected to return
something that was date related.
Like a date string? A Number? How about...

A Date ?

Ding, ding, ding!
Wasn't it - String.prototype.parseJSON - that you were objecting to? An
instance method of String object might be executed to turn that string
into anything. As JSON is a structure consisting of and object or array
with optional nested descendants then that is the likely result.
Why is adding the parse method to String correct?

Should the String constructor be morphed into a parser?

Precedence would be a good enough reason, as JavaScript(tm) already
has - toSource - method on objects. All this adds is another form of
serialisation, and one that has obvious practical applications.
JavaScript -- not ES. It's a really old feature, and only Moz/NS4.

While the feature may have practical applications, such applications
are quite limited. Limited to what? Well, mostly to Data Structure.
Object should not always have data structure functionality. Only data
structures should. A Menu, could, for example, be converted to a Data
Structure, or could be so implemented. This would be a design
decision.

Maybe, but not a native code (so relatively fast) method.


Much as objects don't need - toSource - but don't suffer for having it.
toSource is limited to Spidermonkey, AFAIK.

toJSONString will be an ES4 standard.
There is plenty of scope for doing stupid things with the language as it
is.
Exactly! JavaScript lets you do all sorts of things.

"foo".prop
new Script("true");

"foo".big();

So why add another? And besides, toJSONString would be really useful
in a lot of cases. I realize that, really. But, at the same time, I
don't need it on my Tooltip.

Which misuses?
Like the Power Constructor, the Module pattern. These things can and
are often used to make really strange and confusing code. There are
plenty of F/E devs who struggle trying to apply OO concepts to JS and
make judgement calls that create problems down the road.
You have said that before, but still have not posted any demonstration
of this supposed brokenness.

function b() {}
b.prototype.pie = "yes"; // enumerable prop.

var i = new b;
i.propertyIsEnumerable('pie'); // Well, what do you think?
for(var prop in i)
alert(prop); // will it alert "pie"?

What went wrong?

propertyIsEnumerable does not check the prototype chain, but for-in
does.

That is a bug.

Which JScript bug? The one where - dontEnum - attributes are inherited
through the prototype chain when they should not be?
Yes, well, *mostly* the bug itelf is incosistent.

({prototype:1}).propertyIsEnumerable('prototype'); // well, what does
JScript think?

(Function()).propertyIsEnumerable('prototype'); // well, what does
JScript think?

It is not a problem. It has never been feasible to directly use
javascript objects as storage faculties for mapping arbitrary string
keys to values. The 'safe' set of possible keys in such a context don't
suffer from enumeration issues even in IE browsers.
All JScript bugs aside, Object is a generic type. HashMap, or
is specific. It says: I'm a data structure. said:
As useless/irrelevant as - instanceof -.
Well, instanceof was there first. In ES4, it will work across frames.

Why not, it would do no harm if not used, and if used then there would
presumably be some reason for using it.
It will be used. A lot, I think.
What is "bad" about object enumeration?

Enumeration has nothing to do with Object as a type. The feature
causes problems that have been the topic of discussion for years.
Which is already the reality for JavaScript(tm) and that doesn't seem to
have resulted in any problems.
I've had my share of problems with this. Mostly related to the JScript
bug.
Expedience, in the face of a growing use of JSON as a data exchange
medium, and particularly for transmission between HTTP clients and
servers.
JSON is not the panacea, for those who think it is, a native JSON
object will provide the same functionality, and will do nothing other
than provide such functionality.

Maybe, maybe not. What of it, I don't thing I have ever used
propertyIsEnumerable in production code but no objects have suffered for
having that unused method?
Besides being misnamed propertyIsEnumerable is broken.
Why? What is it doing there if you don't want it included in the
serialisation, or if you don't want it why use the prototype
toJSONString method? You are the one doing the programming so program
the system to be what you want it to be.
Because it means that by default, Widget MUST tackle this
responsibility. Widget is Serializable, even if I don't want it to be,
I, as a programmer, have had that right taken away. That sucks.

Yes, a restriction of the nature of property name declarations in the
object literal strings and the types of values that may be assigned to
properties.


Which is what we are doing, taking a JSON string and getting a
javascript object.


They can (or the whole thing would be a non-starter). All you are saying
is that objects can be created that will not translate well. And they
can, but that does not mean that rational programmers will create such
objects.
A Tooltip.show() method seems pretty rational to me. What does that
have to do with data structures?
More like the serialisation process has to be able to deal with (in some
predetermined manner) all possible javascript objects. But that is just
a mater of specification.
Exactly. The serialization has to, and if it doesn't the programmer
has to provide it.

I can see it now, people will want next a way to set a serializable
flag on their properties to make things easier.
HTMLInputElement are not required to have prototype chins or inherit
form Object.protoype so they are irrelevant in the general case. Other
objects have properties with attributes and values regardless of their
'type'.
Not required, but they do, in many browsers. In those cases, it will
be required to deal with serialization.


And Callable is an Object, and a subc'd String is a String.
How is adding JSON methods to all objects justified over adding a
separate Class/Object to handle serialization?
<snip>

How is any of what justified? The proposed methods are an expedient or
harmless addition to the group of methods already on the pertinent
prototypes.
Not harmless when my Tooltip has to be responsible for serializing
itself.

Before having a JSON class implemented, I'd like to see three basic
types supported by a JSON object (like Map, et c).

a JSON Object would do:
serialize
deserialize

For those interested, Robert Sayre is implementing some JSON object
support in Mozilla, something along the lines of Caja.

Garrett
 
P

Peter Michaux

On Oct 22, 7:08 pm, "(e-mail address removed)" <[email protected]>
wrote:

[snip about propertyIsEnumerable bug]

[snip about IE for-in enumeration bug]

[snip about object enumeration is a bad idea]

[snip about object serialization should not be an object property]

[snip about propertyIsEnumerable bug]

[snip about propertyIsEnumerable bug]

[snip about object serialization should not be an object property]

[snip about object enumeration is a bad idea]

[snip about IE for-in enumeration bug]

[snip about object serialization should not be an object property]

[snip about IE for-in enumeration bug]

[snip about object enumeration is a bad idea]


It's starting to be a ball of confusion which are the real problem
that need fixing and which are stylistic "separation of concerns"
issues. Your recommendations for ES3 to ES4 change have not been
separated. ;-) The real problems need the most attention. Consensus
will likely not be reached on stylistic issues.

I can see that the propertyIsEnumerable and the IE for-in bug seem to
be legitimate problems.

I've never had a problem with the for-in loop. I suppose that means
that when using an object as a hash that is subsequently enumerated
with for-in in IE, I have never added a "prototype" hash key. Is that
what this boils down to? This definitely seems to be something that
should be fixed.

It may be that most people don't really care if parseJSON is a
property of String or String.prototype or some JSON object. I know
that for functionality like serialization I care most that the
implementations work as specified. The JavaScript language is
considered by most to be a mess and there is no chance of attaining
any purity so where the JSON functions live is not so important to me.
If API structure was something that I allowed to bother me daily I'd
have popped by now working with JavaScript.

I definitely recommend dropping your recommended change from
propertyIsEnumerable to isPropertyEnumerable. If the target is moving,
the browser makers will never all hit it at the same time or ever.
This naming issue is completely superficial and detracts from other
more important and numerous recommendations perhaps to the point that
all recommendations will be ignored.

Peter
 
D

Dr J R Stockton

In comp.lang.javascript message <[email protected]
glegroups.com>, Mon, 22 Oct 2007 22:09:19, "(e-mail address removed)"
The return type is incorrect. Even in Java's Date object (which has
it's problems) Date.parse returns a Date (normal). The problem is that
you can't parse localized dates based on a string. It's impossible.

You can do it in javascript if the localisation is known, by first using
RegExp replace to convert all-numeric dates to YYYY/MM/DD and if
necessary to convert YY to YYYY. And to translate months to English.

In future, new Date(String) could be enhanced to recognise roman
numerals for months. I've seen evidence suggesting that some Europeans
like that.

That does not, however, accommodate non-Gregorian localisations.
 
T

Thomas 'PointedEars' Lahn

Objects are used for collections. There are no other collection types in
ES3.

There are _no_ collection types at all in ES3 or in the current ES4 draft.
Objects are used for other things than collections, most of the time.

Objects are used as objects. Collections (as in HTMLCollection) have the
additional feature of having their elements being accessible both by
numerical and by alphanumerical name. There are no such built-in objects.
The conflation of Object and Hashtable causes problems in ES. Adding
toJSONString further complicates Objects with more responsibility.

Utter nonsense. There is no Hashtable in ES3 or ES4 (yet). Adding a
toJSONString method to Object.prototype that has the attribute DontEnum
complicates nothing.
The return type is incorrect.

It can't be incorrect because we are talking about the language
specification. The return type may be unwise, but that is a matter for
debate. I have showed why I don't think it is unwise (which you snipped)
and you have avoided to rebut that.
Even in Java's Date object (which has it's problems) Date.parse returns a
Date (normal).

The relevance of the Java API Specification regarding the current or future
edition of the ECMAScript Language Specification is exactly zero.
The problem is that you can't parse localized dates based on a string.

Yes, you can. However, parsing user-defined date input strings is known to
be unwise, as those are ambiguous.
It's impossible.

It's not. ES3 15.9.4.2 shows how.
W/A JSON Object, You could add it yourself w/only a few lines of code:

unit ThomasJSON { internal package ThomasJSON {
Object.prototype.toJSONString = function () { return
JSON.toJSONString(this) };
Object.prototype.propertyIsEnumerable("toJSONString", false); } }

In your code:

use unit ThomasJSON "http://example.com";

But that would be far less efficient than a built-in feature because that
code would have to be JIT-compiled to bytecode and/or interpreted instead
of existing compiled in the script engine code.
What is aso?

"and so on" = "etc." means the rest of the built-in methods.
valueOf should produce testable, consistent results on Date objects

I meant valueOf() alright, and it does.
Date.prototype.toString providing a formatting dependency is a problem.
It is not localized.

As you are convinced that user-defined implementations would be better
than a built-in solution: it can be localized with such code.
toDateString and toTimeString should be on a DateFormatter class.

toString should be for diagnostic info.

You have yet to state *why* you *think* so. You have made a number of bold
statements here, but you have not provided any reasonable explanation for them.
Map<T,T> is a data structure. It's in ES4.

No, it's not. Map as used in subsection 5.2.1 of the current ES4 draft is
purely a specification mechanism, not a language feature:

| 12 Every program visible value is an object. An object is a collection of
| properties.
| 13
| 14 struct Object {
| 15 delegate : Object
| 16 properties : Map<Name,Object>
| 17 type : Traits
Long overdue.

How can a type that can only exist with strict typing it be "long overdue"
if previous editions did not specify strict typing at all?
Depends what 'necessary' means. A lot of necessary things (collections)
are missing in ES3, yet we manage.

Constructor's based on Error (subclass) in ES3 doesn't really work that
well.

ES3 has no classes, but I would like ES4 to provide the possibility to
derive from Error to create my own error classes/prototypes. However,
another exception type is not necessary to handle JSON parsing errors.


PointedEars
 
D

dhtmlkitchen

On Oct 22, 7:08 pm, "(e-mail address removed)" <[email protected]>
wrote:

[snip about propertyIsEnumerable bug]

[snip about IE for-in enumeration bug]

[snip about object enumeration is a bad idea]

[snip about object serialization should not be an object property]

[snip about propertyIsEnumerable bug]

[snip about propertyIsEnumerable bug]

[snip about object serialization should not be an object property]

[snip about object enumeration is a bad idea]

[snip about IE for-in enumeration bug]

[snip about object serialization should not be an object property]

[snip about IE for-in enumeration bug]

[snip about object enumeration is a bad idea]

It's starting to be a ball of confusion which are the real problem
that need fixing and which are stylistic "separation of concerns"
issues. Your recommendations for ES3 to ES4 change have not been
separated. ;-) The real problems need the most attention. Consensus
will likely not be reached on stylistic issues.
What are the most important things then?
I can see that the propertyIsEnumerable and the IE for-in bug seem to
be legitimate problems.

I've never had a problem with the for-in loop.
I have. I use toString and valueOf fairly often, so it gets to be a
problem in IE because IE skips those (and others).

I suppose that means
that when using an object as a hash that is subsequently enumerated
with for-in in IE, I have never added a "prototype" hash key. Is that
what this boils down to? This definitely seems to be something that
should be fixed.

No, what happens, in IE, is that IE will skip anything prop on an obj,
when a corresponding obj in the prototype chain has DontEnum. IE does
not skip a property named "prototype", well, unless it's a function.
aFunction.prototype would be enumerable.


[snip about parseJSON]
I definitely recommend dropping your recommended change from
propertyIsEnumerable to isPropertyEnumerable.
People get confused. I did, for a long time, I would write
"isPropertyEnumerable", then feel like an idiot when I got the error.
Webkit guys wanted a rename.

Flash DID rename propertyIsEnumerable. They've got an
isPropertyEnumerable method. From the looks of it, it does the same
thing.

If the target is moving,
the browser makers will never all hit it at the same time or ever.
This naming issue is completely superficial and detracts from other
more important and numerous recommendations perhaps to the point that
all recommendations will be ignored.
Yeah, it is not the most important thing. I agree, and in fact, even
if propertyIsEnumerable got fixed, it wouldn't have as significant an
impact on the language as a lot of the other stuff in ES4.

BTW, what ever happened to the partials idea?

Garrett
 
D

dhtmlkitchen

There are _no_ collection types at all in ES3 or in the current ES4 draft.


Objects are used as objects. Collections (as in HTMLCollection) have the
additional feature of having their elements being accessible both by
numerical and by alphanumerical name. There are no such built-in objects.


Utter nonsense. There is no Hashtable in ES3 or ES4 (yet). Adding a
toJSONString method to Object.prototype that has the attribute DontEnum
complicates nothing.



It can't be incorrect because we are talking about the language
specification. The return type may be unwise, but that is a matter for
debate. I have showed why I don't think it is unwise (which you snipped)
and you have avoided to rebut that.


The relevance of the Java API Specification regarding the current or future
edition of the ECMAScript Language Specification is exactly zero.


Yes, you can. However, parsing user-defined date input strings is known to
be unwise, as those are ambiguous.


It's not. ES3 15.9.4.2 shows how.








But that would be far less efficient than a built-in feature because that
code would have to be JIT-compiled to bytecode and/or interpreted instead
of existing compiled in the script engine code.



"and so on" = "etc." means the rest of the built-in methods.


I meant valueOf() alright, and it does.


As you are convinced that user-defined implementations would be better
than a built-in solution: it can be localized with such code.



You have yet to state *why* you *think* so. You have made a number of bold
statements here, but you have not provided any reasonable explanation for them.



No, it's not. Map as used in subsection 5.2.1 of the current ES4 draft is
purely a specification mechanism, not a language feature:
No, there's really a Map! It's a new built-in.

The overview.pdf is here:
http://www.ecmascript.org/docs.php

It's a pretty easy read, so good for those who want a quick overview.

| 12 Every program visible value is an object. An object is a collection of
| properties.
| 13
| 14 struct Object {
| 15 delegate : Object
| 16 properties : Map<Name,Object>
| 17 type : Traits


How can a type that can only exist with strict typing it be "long overdue"
if previous editions did not specify strict typing at all?
I don't know quite what you're asking. Do you mean Parameterized type,
or strict mode?

It's a useful construct, regardless.

ES3 has no classes, but I would like ES4 to provide the possibility to
derive from Error to create my own error classes/prototypes. However,
another exception type is not necessary to handle JSON parsing errors.
ES4 will offer classes. Real classes, with bound instance methods, and
types (if you want them). After dealing prototype-based constructor
chaining, Scope augmentation tricks, losing my object refs in
setTimeout, I really welcome this feature.

I think you'll be able to extend built in Error. I'm not sure about
this, but you can try it in the reference impl, on ecmascript.org.
 
R

Richard Cornford

The first page of the document says

"ES4 is compatible with ES3 and adds..."

I suppose that adding reserved words to the language is
not quite an exception to this statement but ES3 code
won't necessarily run as ES4 code if there are new
keywords in the language.

If any ES3 code won't run (and behave the same as it would in an ES3
environment) then there is no compatibility with ES3.
The Perl and PHP programs would be smug when observing
a situation like this with their @foo and $bar identifiers.

And maybe even more smug if you consider that the solution might be as
simple as to have all new keywords prefixed with, say, '#' and so
prevent them from ever resembling ES3 Identifiers.

Richard.
 
R

Richard Cornford

The example was taken from Java, to illustrate the concept
that XXX.parse is usually expected to return an XXX.

If three is one running theme in your posts to this group it is that
your expectations don't match up very well with javascript.
parseInt should be a Number function, not global.parseInt.

Number.parseInt

Wouldn't the implication of your previous statement be that if -
parseInt - was a method of the number constructor then its output would
be a Number object not a number primitive?
BTW, global is accessible in ES4.

Like a date string? A Number? How about...

A Date ?
Any.

Ding, ding, ding!

Why is adding the parse method to String correct?

It is neither correct nor not correct. Rather it seems to be expedient
and harmless otherwise.
Should the String constructor be morphed into a parser?


JavaScript -- not ES. It's a really old feature, and only
Moz/NS4.

That doesn't matter in context. The method exists, has existed for some
considerable time, and it has (and is having) no negative impact on the
use of objects in JavaScript(tm) or ECMAScript. Ignoring its existence
is sufficient, and any second similar serialising method can just as
effectively be ignored when not wanted with the same outcome.
While the feature may have practical applications, such
applications are quite limited. Limited to what? Well,
mostly to Data Structure. Object should not always have
data structure functionality. Only data structures should.
A Menu, could, for example, be converted to a Data Structure,
or could be so implemented. This would be a design decision.

As it stands javascript only has one object type, and augments that
object to create what then become its various built-in types. Then
programmers who want multiple 'types' of object set about augmenting the
native ECMAScript object into the various 'types' they want. In the end
there is still not actual distinction between the 'type' of these
objects beyond what has been done to them and how they will be used. And
that distinction comes from the programmer not the language.

If the programmer declares that 'these objects are data structures' and
'these objects are not' then that is his/her design decisions, but the
objects themselves are still all just the native ECMAScript object in
reality. Thus, even if all the objects have serialisation method (and in
JavaScript(tm) they already do) then the distinction between a 'data
structure' and 'not a data structure' may be no more than calling the
serialisation methods of the first and never calling it on the latter.

This is the reality of tiring to do OO programming in a language as
loosely typed as javascript. There is no 'type safety' and the
programmer is the one responsible for staying on top of that and
understanding how the notions of 'type' from their design are to be
used/handled in the resulting program.
toSource is limited to Spidermonkey, AFAIK.

It is quite widespread in implementations that attempt to be
JavaScript(tm) compatible in addition to being ECMA 262 compatible. But
regardless of that, electing never to use a method that an object may
have is not significantly distinct from using an object that never had
the method to start with.
toJSONString will be an ES4 standard.

Exactly! JavaScript lets you do all sorts of things.

"foo".prop
new Script("true");

"foo".big();

So why add another?

Because the addition you are talking about makes no practical
difference. It does not introduce anything new (object serialisation has
been a reality for a considerable time already) and so its only
contribution to the ability of 'programmers' to do stupid things is
providing another Identifier that can be put after a dot and before an
arguments list without the result actually erroring on the spot.
And besides, toJSONString would be really useful
in a lot of cases. I realize that, really. But, at
the same time, I don't need it on my Tooltip.

Then don't call it. Your tool tip manages to get by without you
calling - toSource - on it.
Like the Power Constructor, the Module pattern.

These are examples of "misuses" of "for-in loops, or closures"?
These things can and are often used to make really
strange and confusing code.

"Confusing code" can often be a matter of experience and knowledge. As a
relative novice you will tend to be confused by many of the more
advanced constructs used in javascript, and perceive some of those
constructs as strange. That is inevitably true for anyone coming anew to
any programming language.

It is also possible for code that is inherently strange and confusing
(to any audience) to be written in any programming language.

What is needed with of your response to my request for examples of
"misuses of for-in loop, or closures" is some evidence for "the Power
Constructor" and "the Module pattern" being such "misuses". Or even of
their being inherently "strange and confusing". Otherwise we are left
with your unsubstantiated assertions, and may be included to attribute
them as the result of ignorance on your part rather than being anything
of significance.

Take "the module pattern" (as I am largely responsible for its
existence); about 6 months into to the development of the module pattern
the question of singleton pattern implementations came up, and it
rapidly became obvious that the module pattern lent itself extremely
will to that particular application. So much so that most introductions
to the module pattern have employed a singleton pattern as their primary
demonstration of the application of the module pattern (including the
well-known YUI article, where the name got attached to the technique).

On your web site you have a section headed "Design Patterns" which seems
to contain a single article that is a singleton pattern implantation:-

<URL: http://www.dhtmlkitchen.com/?tq=Design Patterns >

- which I find strange, and many novices would certainly find confusing.
One of the main things about your code that I find strange is its
ham-fisted attempt to achieve a notion of 'private' for an exposed
'class' constructor. Having a constructor for an object that you only
intend to ever have one instance of is itself a strange design decision
in javascript, as an object literal is an ideal structure for defining
an object that will only ever be a single unique object instance. But
the really strange thing in your code is that it employs the
JavaScritp(tm) extension - Array.prototype.indexOf - method in the code
that is supposed to very that the 'class' constructor is not directly
used by external code, and so will not work at all with any JScript
versions. That is strange because any 'Design Pattern' that cannot be
used with IE browsers has virtually no commercial applications at all
and so is virtually worthless.

Another strange aspect of your implementation of "private" for the
'class' constructor is how trivial it is to subvert. All a programmer
has to do in order to use the singleton 'class' constructor directly is
first execute:-

Function.entryCheck = function(){return;};

- and all 'protection' is gone. There are two attitudes towards the
notion of 'protected' in javascript; the one that says that you can
achieve everything necessary with naming conventions and documentation,
and so avoid the runtime overheads of the alternatives, and the one that
says that programmers using the code cannot be trusted to obey the
naming conventions and documentation and so things that should be
'protected' must be properly protected, despite the overheads. Either
are valid positions to take, but you seem to be going for the latter,
where the programmer cannot be trusted to use the system as designed and
so must be prevented from abusing it. But then you leave the door wide
open for this abusive programmer to knock your 'protection' out at a
single stroke, when you have already decided that he/she is precisely
the sort of programmer who will do just that sort of thing (that is, you
have decided that documentation saying that the singleton constructor is
not to be used directly will be disregarded, but expect the same
individual not to subvert your 'protection').

Here we see the advantage of Douglass Crockford's realisation that
closures could be used to provide some real 'protection', and the
extension of that idea into the 'module pattern' (and related concepts).
Protection with closures becomes physical, and subverting it becomes so
involved that the individual trying to subvert it may as well just
re-write the 'protected' code the way they want it and forget about the
original.

A 'module pattern' singleton implementation of your singleton "Design
Pattern" could go:-

var Tooltip = (function(){
var instance;
return ({
getInstance:function(){
return (
(instance) ||
(instance = {
ACTUATOR_CLASSNAME : "tooltip",
show:function(){
//some code.
}
})
);
},
purgeInstance:function(){
// Clean up all listeners.
instance = null;
}
});
})();

- and require half the code (not needing the elaborate and pointless
'protection' methods of the Function constructor or a constructor of its
own), achieves superior protection because it becomes a simple
impossibility to call any singleton 'class' constructor directly because
there is no such constructor, and because the code is 100% ECMA 262 3rd
Ed. code the result is also compatible with IE and so does have
commercial viability.


Now that code will likely be confusing to novices, and probably
surprising to people coming to javascript from other languages (and
particularly to those expecting javascript to be a cut-down Java).
Indeed I well remember being surprised the first time I observed the
inline execution of a function expression back in November 2002:-

<URL:
http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/4eda01126dd6ea8c >

(That post may include the first example of the inline execution of a
function expression ever. I would be interested in any examples
pre-dating that one, but those of you who remember Yann-Erwan Perio
(Yep) will recall that he was just the sort of playfuly inventive coder
that easuly could be the first to employ such a construct ever.)

My first reaction to seeing that was "you can't do that", shortly
followed by "****, you _can_ do that", and then "If you can do that then
.... " whole new horizons of possibilities open up which eventually
(mixing in the influence of Douglas Crockford's emulation of private
instance members) leads to the creation of the module pattern by May of
the following year.

So yes, for module pattern code not to be surprising and confusing you
need to understand function expressions, lexical scopeing and closures,
and maybe have been shown how it works once or twice, but that isn't
really any more than saying that you need to understand javascript in
order to understand javascript code. There is nothing inherently strange
or confusing in the pattern itself.

There are plenty of F/E devs who struggle trying to apply
OO concepts to JS and make judgement calls that create
problems down the road.

So people who struggle to do their jobs may not do those jobs
particularly well? That is hardly a revelation.

function b() {}
b.prototype.pie = "yes"; // enumerable prop.

var i = new b;
i.propertyIsEnumerable('pie'); // Well, what do you think?
for(var prop in i)
alert(prop); // will it alert "pie"?

What went wrong?

Nothing went wrong. The - propertyIsEnumerable - method did exactly what
it was specified as to do. If you see that as wrong then its is your
expectations that need adjusting.
propertyIsEnumerable does not check the prototype chain,
but for-in does.
Absolutely.

That is a bug.

No, it is the way things have been designed to be. Maybe that was not
the best of design decisions, but still everything is behaving in
accordance with the design.
Yes, well, *mostly* the bug itelf is incosistent.

No, that big is consistent. If you perceive it as inconsistent that just
means you are yet to properly identify the cause and effect
relationships that apply to it. Computers are inherently consistent, and
so bugs are also inherently consistent.
({prototype:1}).propertyIsEnumerable('prototype'); // well,
what does JScript think?

JScript objects have no - prootype - property on their prototype chains
to inherit so they cannot erroneously inherit a - DontEnum - attribute
through their prototype chain.
(Function()).propertyIsEnumerable('prototype'); // well, what does
JScript think?

Dynamically created function objects each have a - prototype - property
themselves, and it should not be marked with the - DontEnum - attribute
so this is an ECMAScript bug, though not the same bug as the prototype
chain inherited -DontEnum - bug because there should (by default) be no
objects on a function object's prototype chain with a - prototype -
property (as their prototype chains consist only of Function.prototype
and Obejct.prototype, neither of which have a - prototype - property by
specification).
All JScript bugs aside, Object is a generic type. HashMap, or
Map<String,Object>, is specific.

Not in ECMAScript 3, as there is only one object type there.
It says: I'm a data structure.

Or the programmer says it is a data structure.
Well, instanceof was there first.

"First" in the sense of them both being introduced in ECMA 262 3rd Ed.?
In ES4, it will work across frames.

So no back-compatibility there either.
It will be used. A lot, I think.

It will be used where using it is useful, not in an arbitrary manner
with any object that may come along.
Enumeration has nothing to do with Object as a type.
Explain.

The feature causes problems that have been the topic
of discussion for years.

The vast majority of those problems being the direct result of
individuals having unrealistic expectations of how enumeration of object
properties should work and so having their expectations disappointed by
reality. Start out with realistic expectations and no issues follow
(mostly because 90% of the apparent applications of enumeration are then
seen as inappropriate and better alternatives employed in their place).
I've had my share of problems with this. Mostly related
to the JScript bug.

Maybe you have, but you have expectations that are not technically
informed or realistic, so you are likely to encounter issues. That is
just a symptom of your being a relative novice at javascript. As you
learn the language these problems will go away.
JSON is not the panacea,

Did anyone say it was? It is just something that is going to be used,
probably used increasingly (possibly replacing XML/SOAP in all browser
client-server data exchanges) and something that will benefit form
handling in native code rather than (inevitably slower) javascript code.
for those who think it is, a native JSON object will provide
the same functionality, and will do nothing other than
provide such functionality.


Besides being misnamed propertyIsEnumerable is broken.

You are yet to present any evidence for this 'brokeness'.
Because it means that by default, Widget MUST tackle this
responsibility. Widget is Serializable, even if I don't want it
to be,

Don't want it to be serializable or don't' want it to be serialized? In
both cases that is already no more than a whim on the part of the
programmer because the existence of - toSource - means it already is
serialzable.
I, as a programmer, have had that right taken away. That sucks.

You have not lost the right to 'want' and you never had a reason to
'expect'.

A Tooltip.show() method seems pretty rational to me. What does that
have to do with data structures?

What does it have to do with JSON, given that JSON sub-set of object
literal notation precludes properties with function values?
Exactly. The serialization has to, and if it doesn't the programmer
has to provide it.

I can see it now, people will want next a way to set a serializable
flag on their properties to make things easier.

That seems reasonable under the circumstances.
Not required, but they do, in many browsers.

Some do and some don't. You don't create cross-browser code by assuming
thing will exist when they actually may or may not exist.
In those cases, it will
be required to deal with serialization.

Well, they already do where - toSource - exists along side input
elements inheriting form Object.prototype. People seem to get by with
things the way they are.
And Callable is an Object, and a subc'd String is a String.

What are you talking about?
How is adding JSON methods to all objects justified over
adding a separate Class/Object to handle serialization?

Visibility would be one justification. As a method of object instances
the serialization method is no more problematic or significant than
toSource, but stuff a new object 'class' into the global namespace and
there will be knock-on effects for compatibility.
Not harmless when my Tooltip has to be responsible for serializing
itself.
<snip>

What do you mean by "responsible for serializing itself"? If you don't
want a sterilized tool tip don't call the method and you will not have
one.

Richard.
 

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,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top