Return values of mutating MOP operations (Was: response chapter 8 except 8.5 (was Re: ES6 Rev13 Review: MOP-refactoring, symbols, proxies, Reflect module))

Allen Wirfs-Brock allen at
Wed Jan 2 10:02:19 PST 2013

On Dec 31, 2012, at 4:27 AM, Tom Van Cutsem wrote:

> 2012/12/31 Allen Wirfs-Brock <allen at>
> responses for chapter 8, except for 8.5 which will get its own message.
> On Dec 29, 2012, at 2:37 PM, Tom Van Cutsem wrote:
> > Table 8:
> >   * [[PreventExtensions]] internal method: should return a Boolean success value
> Why?  no caller of [[PreventExtension]] currently uses such a result.  In general, we did try to make more of the internal methods return true/false success indicators rather than deeply burying the decision of whether or not an exception should be generated on failure.  Do you have something in mind where a caller of [[PreventExtension]] within the spec. (or a caller of Reflect.preventExtensions) needs a true/false success code?  Or maybe we should just do it for consistency sake.
> Three reasons:
> 1) As you say, consistency with [[DefineOwnProperty]], [[Delete]] and [[Set]] (maybe also [[SetInheritance]]). Every operation that mutates an object returns a success code indicating whether or not the intended change took place.
> 2) Before proxies and symbols, [[PreventExtensions]] could never fail. With the advent of new exotics, this operation may be "rejected". Proxies and symbols need a way to signal this. Essentially Object.preventExtensions should throw a TypeError when [[PreventExtensions]] return false. Object.preventExtensions should never fail silently on a proxy that rejects the operation.

Symbols don't need to fail on [[PreventExtensions]].  It always succeeds for them since they are born non-extensible.

The major user facing change here is the possibility that Object.preventExtensions will through if the object can not be made non-extensible.  This wasn't specified  in ES5, but I'm ok making that change.

> 3) It would be really useful if Reflect.preventExtensions returned the boolean success code, as this provides an easier way to test if this operation succeeded than is possible with Object.preventExtensions. Compare:
> if (Reflect.preventExtensions(obj)) { /* success code */ } else { /* failure code */ }
> vs.
> try {
>   Object.preventExtensions(obj);
>   /* success code */
> } catch (e) { if (!(e instanceof TypeError)) throw e; // not even a fool-proof test
>   /* failure code */
> }

OK, [[PreventExtensions]] not returns a boolean

> >   * [[Delete]]: I would remove "because its [[Configurable]] attribute is false." from the description. Proxies and host objects may return false for other reasons as well (cf. the recent discussions about DontDelete vs. configurable:false)
> Do you have some alternative wording?  These descriptions (along with whatever eventually goes into  are intended to be the informal description of the contract of these MOP methods.  What is true or false actually intended to mean for [[Delete]]?  Is it that false means:  the property exists but the property wasn't deleted?
> The success code for [[Delete]] is indeed fuzzy as it may mean:
> a) the property was/was not successfully deleted
> b) the property is / is no longer present
> Since deleting a non-existent property returns true, b) is closer to the existing semantics.
> Here's my alternative wording:
> [[Delete]] (propertyKey) -> Boolean: "Removes the own property indentified by the propertyKey parameter from the object. Return false if the property was not deleted and is still present. Return true if the property was deleted or was not present."

Good, I'll use that language.


> Cheers,
> Tom

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list