Closed Bug 296347 Opened 20 years ago Closed 20 years ago

most "intentionally generic" methods are not generic

Categories

(Core :: JavaScript Engine, defect)

x86
Windows XP
defect
Not set
minor

Tracking

()

RESOLVED INVALID

People

(Reporter: stryker330, Unassigned)

Details

Attachments

(1 file)

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.8) Gecko/20050511 Firefox/1.0.4
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.8) Gecko/20050511 Firefox/1.0.4

The ECMAScript specification states that certain methods should be generic, i.e.
they could be called on objects that they aren't methods of with expected
results.  For example:

The reverse function is intentionally generic; it does not require that its this
value be an Array
object. Therefore, it can be transferred to other kinds of objects for use as a
method. Whether the
reverse function can be applied successfully to a host object is
implementation-dependent.

That means Array.prototype.reverse.call('some string') should work properly. 
However, for most methods, it doesn't work.

I didn't test all the methods, but I'll mention a couple:

any method - strings are never modified (not sure whether they should anyway)
Array.prototype.reverse.call(string) - returns the input
Array.prototype.sort.call(string) - returns the input
Array.prototype.pop.call(string) - correctly returns the last character (though
string, as usual, isn't modified)
Array.prototype.concat.call(string, string2) - works as expected (probably
because there's also String.prototype.concat)
String.prototype.indexOf.call(array, value) - returns the index of value * 2

IE (and probably most other browsers) also has the same problem.

Reproducible: Always

Steps to Reproduce:
Attached file testcase
testcase for Array.prototype.reverse and String.prototype.indexOf.

1. Note that no exception is thrown for calling Array.prototype.reverse on a
String however it returns the unreversed string. I believe this is due to fact
that no conversion is specified for |this| and the different [[Put]] method in
Array which is not supported in other objects.

2. Calling String.prototype.indexOf on an Array does return a different value
since by the spec, the |this| argument is first converted to a string which in
this case is a string of the array items separated by commas, then indexOf is
called.

Unless brendan thinks otherwise, I think this bug is invalid.
Most of this is per-spec, but we have extended ECMA-262 to allow

  var s = "hello";
  assert(s[3] == 'l');

to hold.  But of course, you can't do s[3] = 'p' and have s mutate into "helpo".

The way for now to mutate strings is to split them on the empty string into an
array, operate directly on that array, then join on the empty string:

js> s = "hello";
hello
js> a = s.split('')
h,e,l,l,o
js> a.reverse()
o,l,l,e,h
js> s = a.join('')
olleh

Mutable strings cannot be supported compatibly, so will not be.  They make for
confusion without type annotations.  A string in JS appears to be a shared and
immutable array of characters, although implementations may optimize in certain
cases to reuse buffers.

This bug's Summary is not accurate.  If you want to file a new bug asking for a
mutable string buffer type in JS2, please do that.  I don't mind if you reopen
and morph this bug, but I'm marking INVALID for now.

/be
Status: UNCONFIRMED → RESOLVED
Closed: 20 years ago
Resolution: --- → INVALID
I looked more closely at the spec again.  For String.prototype.indexOf:

1. Call ToString, giving it the this value as its argument.
2. Call ToString(searchString).

Similar statements for the rest.

So, I agree that this bug is invalid.  But I wonder why the spec would say
"intentionally generic", when they usually can't be used for generic purposes.
The spec is using generic to mean what it means in language theory: methods not
specific to a certain type.

That these methods don't do what you want on *strings* makes them no less
generic on objects other than Arrays that have length properties counting one
higher than the highest non-negative index.  Again, if you want a mutable string
subtype, file a bug or morph this one.

/be
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: