Re: Return values of mutating MOP operations (Was: response chapter 8 except 8.5 (was Re: ES6 Rev13 Review: MOP-refactoring, symbols, proxies, Reflect module))
On Dec 31, 2012, at 4:27 AM, Tom Van Cutsem wrote: 2012/12/31 Allen Wirfs-Brock al...@wirfs-brock.com 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 8.1.6.3) 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. Allen Cheers, Tom ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Return values of mutating MOP operations (Was: response chapter 8 except 8.5 (was Re: ES6 Rev13 Review: MOP-refactoring, symbols, proxies, Reflect module))
2013/1/2 Allen Wirfs-Brock al...@wirfs-brock.com Symbols don't need to fail on [[PreventExtensions]]. It always succeeds for them since they are born non-extensible. Sounds reasonable. 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. Ok. Recall that in the old Proxy API, we already had the fix() trap returning a boolean, and Object.{preventExtensions,seal,freeze} throwing on false. Cheers, Tom ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Return values of mutating MOP operations (Was: response chapter 8 except 8.5 (was Re: ES6 Rev13 Review: MOP-refactoring, symbols, proxies, Reflect module))
2012/12/31 Allen Wirfs-Brock al...@wirfs-brock.com 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. 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 */ } * [[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 8.1.6.3) 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. Cheers, Tom ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss