C. Scott Ananian (2014-03-04T18:21:11.000Z)
On Tue, Mar 4, 2014 at 12:23 PM, Allen Wirfs-Brock
<allen at wirfs-brock.com> wrote:
> There's actually a big difference between %TypedArray%.from and Array.from.
> The typed array version must accurately determine the number of elements in
> the new array be instantiating it.  The regular array can pre-instantiate
> the new array and dynamically adjust its length. This affects a number of
> details of the algorithms. There are other cases where there are variations
> to the array method algorithms necessary to deal with the potential
> spareness of regular arrays.

This is an optimization that would be potentially useful in
`Array.from` as well in many cases.
The spec should allow this optimization for both `Array.from` *and*
`TypedArray.from` -- but we don't need to hardcode the optimization
into the spec.

That is, if the current `Array.from` spec has side-effects that
prohibit a "copy to a helper first" implementation, that should
probably be fixed.  As an example, if an exception is thrown halfway
through iteration through an iterable argument the intermediate writes
remain invisible if the receiver is `Array` or `%TypedArray%`, so the
"copy to a helper" optimization can be safely performed by the
implemention in these cases; it doesn't need to be written into the
spec.

> This is the case for several of the array methods but for many of them, the
> same algorithmic description can be used for both Arrays and Typed Arrays.
> In those cases, the ES6 spec. doesn't duplicate the algorithm but instead
> the Typed Array method specification simply reference the corresponding
> Array method specification. For example:
> http://people.mozilla.org/~jorendorff/es6-draft.html#sec-%typedarray%.prototype.foreach

And my suggestion here was that reference could be even shorter if you
just incorporated a `GetLength` helper that discriminated between
typed arrays and arrays.  Then you wouldn't need the weasel-word text,
you could just say "the implementations are the same".

And, of course, for users it's one more place where they don't have to
worry about the difference between `TypedArray` and `Array`.  "Almost
the same" is a bug waiting to happen.

> There was one issue I had to make a decision on.  In the cases where the
> same algorithm was applicable to both Array and typed Array should a single
> (same identify) function be used in both Array.prototype and
> %TypedArray%.prototype or should a distinct function be used for each.  I
> choose the latter because it seems to allow for more implementation
> flexibility.  There are lots of ways that some of these algorithms might be
> optimized if you know you are dealing with a typed array. I wanted to give
> implementations that option and the most straightforward way to do so is to
> simply say that, for example, Array.prototype.foreach and
> %TypedArray%.prototype.forEach are distinct function objects.  That way they
> can have distinct implementations.  However, if an engine whats to share the
> same implementation level code between the two functions it could still do
> that.

I should let the implementors weigh in, but I believe this is exactly
backwards for modern JavaScript implementations.  The JIT is already
doing function optimizations based on receiver and argument types,
etc, so it's already the case that a single "JavaScript Function
Object" has a number of different "implementation level codes".
There's no benefit to the implementor in differentiating the function
objects -- and doing so introduces a new and clever way to add bugs to
your code.  ("Oh, sorry, `arg.map` isn't actually generic if you
happen to pass a typed array as `arg`....").
  --scott
domenic at domenicdenicola.com (2014-03-07T21:43:50.698Z)
On Tue, Mar 4, 2014 at 12:23 PM, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:
> There's actually a big difference between %TypedArray%.from and Array.from.
> The typed array version must accurately determine the number of elements in
> the new array be instantiating it.  The regular array can pre-instantiate
> the new array and dynamically adjust its length. This affects a number of
> details of the algorithms. There are other cases where there are variations
> to the array method algorithms necessary to deal with the potential
> spareness of regular arrays.

This is an optimization that would be potentially useful in
`Array.from` as well in many cases.
The spec should allow this optimization for both `Array.from` *and*
`TypedArray.from` -- but we don't need to hardcode the optimization
into the spec.

That is, if the current `Array.from` spec has side-effects that
prohibit a "copy to a helper first" implementation, that should
probably be fixed.  As an example, if an exception is thrown halfway
through iteration through an iterable argument the intermediate writes
remain invisible if the receiver is `Array` or `%TypedArray%`, so the
"copy to a helper" optimization can be safely performed by the
implemention in these cases; it doesn't need to be written into the
spec.

> This is the case for several of the array methods but for many of them, the
> same algorithmic description can be used for both Arrays and Typed Arrays.
> In those cases, the ES6 spec. doesn't duplicate the algorithm but instead
> the Typed Array method specification simply reference the corresponding
> Array method specification. For example:
> http://people.mozilla.org/~jorendorff/es6-draft.html#sec-%typedarray%.prototype.foreach

And my suggestion here was that reference could be even shorter if you
just incorporated a `GetLength` helper that discriminated between
typed arrays and arrays.  Then you wouldn't need the weasel-word text,
you could just say "the implementations are the same".

And, of course, for users it's one more place where they don't have to
worry about the difference between `TypedArray` and `Array`.  "Almost
the same" is a bug waiting to happen.

> There was one issue I had to make a decision on.  In the cases where the
> same algorithm was applicable to both Array and typed Array should a single
> (same identify) function be used in both Array.prototype and
> %TypedArray%.prototype or should a distinct function be used for each.  I
> choose the latter because it seems to allow for more implementation
> flexibility.  There are lots of ways that some of these algorithms might be
> optimized if you know you are dealing with a typed array. I wanted to give
> implementations that option and the most straightforward way to do so is to
> simply say that, for example, Array.prototype.foreach and
> %TypedArray%.prototype.forEach are distinct function objects.  That way they
> can have distinct implementations.  However, if an engine whats to share the
> same implementation level code between the two functions it could still do
> that.

I should let the implementors weigh in, but I believe this is exactly
backwards for modern JavaScript implementations.  The JIT is already
doing function optimizations based on receiver and argument types,
etc, so it's already the case that a single "JavaScript Function
Object" has a number of different "implementation level codes".
There's no benefit to the implementor in differentiating the function
objects -- and doing so introduces a new and clever way to add bugs to
your code.  ("Oh, sorry, `arg.map` isn't actually generic if you
happen to pass a typed array as `arg`....").