Re: Non-constructible constructors and Arrays

On 8/3/11, Allen Wirfs-Brock <allen@wirfs-brock.com> wrote:
> On Aug 3, 2011, at 10:24 AM, Garrett Smith wrote:
>
>> On 8/3/11, Allen Wirfs-Brock <allen@wirfs-brock.com> wrote:
>>>
>>> On Aug 2, 2011, at 4:47 PM, Cameron McCormack wrote:
>>>
>>>> On 3/08/11 4:04 AM, Allen Wirfs-Brock wrote:
>>>>> Well, it's inherent in the ES specification's algorithm for each
>>>>> method whether or not it mutates its this value.  We might consider
>>>>> adding a non-normative note that further identifies such methods as
>>>>> mutating or non-mutating but that doesn't really add any additional
>>>>> information that isn't already available to browser implementors.
>>>>
>>>> It's probably "obvious" in some sense, but it's the kind of thing I
>>>> don't
>>>> really like to leave open to interpretation.
>>>
>>> I won't argue one way or another about obviousness, but the ES51 spec is
>>> certainly precise WRT which of these methods mutate and which don't.
>>> There
>>> is no room for interpretation but of course erroneous readings are always
>>> possible.
>>>
>> Does [1].reverse() mutate the object that it's called on?
>> Unambiguously, no, right? So you have methods that will throw
>> sometimes and not others.
>
> Sure it does.  algorithm lines 6.h..i, 6.h.ii, 6.i.i, 6.i.ii, 6.j.i, 6.j.ii

Those steps aren't taken. Revisiting your frozen array example from an
earlier post, this variation:

  var a = [1];
  Object.freeze(a);
  a.reverse();

- does not err, yet:-

  var a = [1,2];
  Object.freeze(a);
  a.reverse();

- does.

> all perform mutating calls upon the this value.  Whether or not  they are
> actually executed depends upon the actual length of the "array".  The
> mutating/non-mutating classification criteria for these methods should be
> whether or not the algorithm includes steps that directly perform mutating
> operations upon the this object.

Exactly. That's what I'm talking about.  What you have now isn't
explicitly tagged doesn't err consistently, as shown in my example.

Why don't these methods fail fast, such that step 0 checks to see if O
is frozen?

It doesn't matter whether or not those
> steps are are not performed for some specific this object values.
>
>>
>> If you tag these methods as mutating non/mutating, any system using
>> them can "fail fast."
>
> We are just talking about specification, not implementation.  Nothing in my
> suggested specification technique prevents an implementation from fast
> failing.
>
> We are really talking about whether I should add additional non-normaltive

You could use something like "frozen array" or "if the array is
frozen, an error is thrown." Any API that does that builds on top of
what ES5 does today, which lets frozen Arrays go through `reverse()`,
waiting until step 6.h.i is called.

You proposed that if one wants to find out if the method will throw or
not, he must read the algorithm. I think that's too much to ask.

The implication is that when then when the algorithm gets to a step
that calls [[Put]] or [[Delete]], he must read through that, then read
through [[Delete]]'s call to [[Configurable]], and all of that just to
see if the method will throw. And then in reading through that, you
see there are cases where the algorithm might not throw, even if
[[Configurable]] and/or [[Writable]] is false. That's  overwhelming.

Why not have array methods make an initial check to see if the object
it is called on is frozen? And if that is done, why not have that
check be applied to a category of "frozen" arrays, so as to avoid
scatter, clutter, and post-hoc specification shotgun surgery? Methods
that throw if the array is frozen: { ... }.
-- 
Garrett

Received on Wednesday, 3 August 2011 18:37:16 UTC