FYI, in case anyone is interested on my user-land solution, there is a (dual) module now, and it's called `self-aware` [1]
It's a slightly revisited, 100% code covered, generic method "patcher" to fix Promise and/or others. Best Regards [1] https://github.com/WebReflection/self-aware#self-aware On Fri, Jul 20, 2018 at 2:17 AM Andrea Giammarchi < [email protected]> wrote: > > one without precedent in the language > > that's how languages move forward, right? > > > It also means you can't `Promise.resolve.call(SubPromise)` > > you can make it more complex and yet have a fallback to the invoker, not a > real issue, just more rules to write down. > > ```js > const withLazyBoundObjects = new WeakMap; > const withLazyBoundMethods = obj => { > const descriptors = Object.getOwnPropertyDescriptors(obj); > Object.keys(descriptors).forEach(key => { > const desc = descriptors[key]; > const {value} = desc; > if (desc.configurable && typeof value === 'function') { > delete desc.value; > delete desc.writable; > desc.get = function () {"use strict"; > const self = this || obj; > let methods = withLazyBoundObjects.get(self); > if (!methods) > withLazyBoundObjects.set(self, methods = Object.create(null)); > return methods[key] || (methods[key] = function () { > return value.apply(this || self, arguments); > }); > }; > } > }); > return Object.defineProperties(obj, descriptors); > }; > > withLazyBoundMethods(Promise); > > class SubPromise extends Promise {} > > console.log([ > (0,Promise.resolve)() instanceof SubPromise, > Promise.resolve() instanceof SubPromise, > (0,SubPromise.resolve)() instanceof SubPromise, > SubPromise.resolve() instanceof SubPromise, > Promise.resolve.call(SubPromise) instanceof SubPromise > ]); > > // [false, false, true, true, true] > ``` > > > > On Fri, Jul 20, 2018 at 1:59 AM Jordan Harband <[email protected]> wrote: > >> That's certainly a clever solution, but one without precedent in the >> language. It also means you can't `Promise.resolve.call(SubPromise)`, >> although perhaps you could avoid that by skipping `.bind` and creating a >> normal function wrapper inside the getter - I'm curious how that might be >> implemented as well as specified. >> >> On Thu, Jul 19, 2018 at 4:54 PM, Andrea Giammarchi < >> [email protected]> wrote: >> >>> My code doesn't suffer what Domenic says. >>> >>> Once again: >>> >>> ```js >>> const withLazyBoundObjects = new WeakMap; >>> const withLazyBoundMethods = obj => { >>> const descriptors = Object.getOwnPropertyDescriptors(obj); >>> Object.keys(descriptors).forEach(key => { >>> const desc = descriptors[key]; >>> const {value} = desc; >>> if (desc.configurable && typeof value === 'function') { >>> delete desc.value; >>> delete desc.writable; >>> desc.get = function (...args) { >>> let methods = withLazyBoundObjects.get(this || obj); >>> if (!methods) >>> withLazyBoundObjects.set(this, methods = Object.create(null)); >>> return methods[key] || (methods[key] = value.bind(this)); >>> }; >>> } >>> }); >>> return Object.defineProperties(obj, descriptors); >>> }; >>> >>> // patch the Promise >>> withLazyBoundMethods(Promise); >>> >>> // have a class that extends Promise >>> class SubPromise extends Promise {} >>> >>> // test inheritance >>> SubPromise.resolve() instanceof SubPromise; // true >>> (0,SubPromise.resolve)() instanceof SubPromise; // true >>> >>> // even the Promise ? >>> Promise.resolve() instanceof SubPromise; // false, it's Promise >>> (0,Promise.resolve)() instanceof SubPromise; // false, it's Promise >>> ``` >>> >>> So, why cannot we have above behavior in core? >>> >>> >>> >>> On Fri, Jul 20, 2018 at 1:36 AM Jordan Harband <[email protected]> wrote: >>> >>>> > TL;DR why aren't public static methods that need context **all** >>>> lazily defined as bound (once) on demand? That would make every single >>>> public static method consistent, accordingly with the Class you extracted >>>> them from, right? That's not clever, that's usually developers expectations >>>> because historically all public static methods don't need the Class to >>>> work. >>>> >>>> I believe >>>> https://github.com/tc39/ecma262/issues/544#issuecomment-236487230 >>>> answers this - specifically, expressing that the claimed better design is >>>> for *nothing* to be bound. >>>> >>>> On Thu, Jul 19, 2018 at 4:22 PM, Andrea Giammarchi < >>>> [email protected]> wrote: >>>> >>>>> Reading that looks like nobody answered my question, explained through >>>>> some code that wouldn't have any issue with subclassing. >>>>> >>>>> So no, there's no answer to my latest question in there, unless I've >>>>> missed it. >>>>> >>>>> On Thu, Jul 19, 2018 at 7:56 PM Jordan Harband <[email protected]> >>>>> wrote: >>>>> >>>>>> This question has been answered here: >>>>>> https://github.com/tc39/ecma262/issues/544 >>>>>> >>>>>> On Thu, Jul 19, 2018 at 9:27 AM, Andrea Giammarchi < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> > Per the KISS principle, let’s avoid to be clever. >>>>>>> >>>>>>> I think my next code example is less clever, but the only reason >>>>>>> I've written hacks or code was not to be advocated or adopted, just to >>>>>>> explain what could happen internally. >>>>>>> >>>>>>> TL;DR why aren't public static methods that need context **all** >>>>>>> lazily defined as bound (once) on demand? That would make every single >>>>>>> public static method consistent, accordingly with the Class you >>>>>>> extracted >>>>>>> them from, right? That's not clever, that's usually developers >>>>>>> expectations >>>>>>> because historically all public static methods don't need the Class to >>>>>>> work. >>>>>>> >>>>>>> On Thu, Jul 19, 2018 at 5:23 PM Claude Pache <[email protected]> >>>>>>> wrote: >>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> > Le 19 juil. 2018 à 16:32, Andrea Giammarchi < >>>>>>>> [email protected]> a écrit : >>>>>>>> > >>>>>>>> > I know it's about subclassing, which is why I've asked why, once >>>>>>>> there's no context, the default/base one is not considered, but since >>>>>>>> everyone came back with the subclassing issue, which is actually what >>>>>>>> I've >>>>>>>> said myself on twitter about the current state, how about changing all >>>>>>>> public static methods that need it, to be getters ? >>>>>>>> > >>>>>>>> > ```js >>>>>>>> > class Promise { >>>>>>>> > #resolve(...args) { >>>>>>>> > return this.nativeImplementation(...args); >>>>>>>> > } >>>>>>>> > get resolve() { >>>>>>>> > return #resolve.bind(this); >>>>>>>> > } >>>>>>>> > } >>>>>>>> > ``` >>>>>>>> > >>>>>>>> > we could argue `Promise.resolve === Promise.resolve` should be >>>>>>>> preserved, as behavior, so that we need a lazy defined getter ... >>>>>>>> **but** >>>>>>>> why not making public static restructuring from known constructors work >>>>>>>> regardless, under all circumstances ? >>>>>>>> > >>>>>>>> >>>>>>>> Nice hack... But it imposes all subclasses of `Promise` that >>>>>>>> override the `resolve` method to use a similar trick, because the >>>>>>>> following >>>>>>>> will break: >>>>>>>> >>>>>>>> ```js >>>>>>>> class MyPromise extends Promise { >>>>>>>> static resolve() { >>>>>>>> // do fancy stuff >>>>>>>> return super.resolve() >>>>>>>> } >>>>>>>> } >>>>>>>> >>>>>>>> const {resolve} = MyPromise >>>>>>>> >>>>>>>> resolve() // TypeError: undefined is not an object >>>>>>>> ``` >>>>>>>> >>>>>>>> Per the KISS principle, let’s avoid to be clever. >>>>>>>> >>>>>>>> —Claude >>>>>>>> >>>>>>>> >>>>>>> _______________________________________________ >>>>>>> es-discuss mailing list >>>>>>> [email protected] >>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>> >>>>>>> >>>>>> >>>> >>
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

