> Why enforcing configurable false?

The fact the lazy getter is called getter, and the fact that a getter
cannot be assigned or the engine throws errors, as opposite of a non
configurable property that will silently ignore the assignment, makes me
think substituting a lazy getter with a fixed getter is the way to.

But I also think being lazy, usually meaning with expensive computations
needed once only, it's a nice to have, and clean guard, to fix that getter
forever.

However, that creates observability of the getter, through its own property
descriptor, but also, as a getter, it might signal side effects, while a
fixed property on the object set as value would indicate there are,
probably, no side effects in accessing it.

TL;DR I'm not fully sure about the getter should be defined, if through its
inherited definition but with a different get callback that returns the
computed value, and only when it comes to classes, or through its own
property accessor, when it comes to objects.

Maybe this is the best way to go though, so that the following code:

```js
const test = {
  x: 123,
  lazy random() {
    return this.x + Math.random();
  }
};

class Test {
  x = 123;
  lazy random() {
    return this.x + Math.random();
  }
}
```

would de-sugar in something like this:

```js
const getDescriptor = (o, k) => (
  o ? (
    Object.getOwnPropertyDescriptor(o, k) ||
    getDescriptor(Object.getPrototypeOf(o), k)
  ) : o
);

const test = {
  x: 123,
  get random() {
    const desc = getDescriptor(this, 'random');
    const value = (function () {
      return this.x + Math.random();
    }).call(this);
    desc.get = () => value;
    Object.defineProperty(this, 'random', desc);
    return value;
  }
};

class Test {
  x = 123;
  get random() {
    const desc = getDescriptor(this, 'random');
    const value = (function () {
      return this.x + Math.random();
    }).call(this);
    desc.get = () => value;
    Object.defineProperty(this, 'random', desc);
    return value;
  }
}
```

preserving whatever behavior previously defined.



On Tue, Jun 12, 2018 at 1:14 PM, <he...@mailbox.sk> wrote:

>
>
> On June 12, 2018 9:44:31 AM GMT+02:00, Andrea Giammarchi <
> andrea.giammar...@gmail.com> wrote:
> >My 2 cents,
> >I use lazy getters since about ever and I'd love to have such syntax in
> >place but I think there is room for some improvement / simplification
> >in
> >terms of syntax.
>
> Yeah I find this better.
>
> Also fixes the this questions by unambiguously setting it to the instance.
>
> >*## Keep it getish*
> >
> >From parsing perspective, introducing `lazy tail()` seems way simpler
> >than
> >introducing `lazy tail:` for the simple reason that everything that can
> >parse `get tail()` and `set tail()` is in place already in every
> >engine. I
> >don't write them but I'm sure having an extra keyboard to catch
> >shouldn't
> >be crazy complicated.
> >
> >*## class compatible*
> >
> >because you used `delete this.tail` and mentioned functional
> >programming,
> >I'd like to underline ES doesn't force anyone to one programming style
> >or
> >another. That means new syntax should play nicely with classes too, and
> >in
> >this case the proposal doesn't seem to address that because of the
> >direct
> >value mutation, as generic property, and the removal of that property
> >from
> >the object, something not needed if inherited.
> >
> >My variant would do the same, except it would keep the value an
> >accessor:
> >
> >```js
> >const take = (n, xs) => n === 0 ? null : xs && {
> >    head: xs.head,
> >    lazy tail() {
> >      return Object.defineProperty(this, 'tail', {
> >        configurable: false,
>
> Why enforcing configurable false? When you use get x() / set x() syntax,
> it leaves the thing configurable true. I feel it is more consistent to have
> the replaced getter copy configurable from existing status quo, that is,
> what is actual configurable of this.tail.
>
> And of course, Object.defineProperty family needs a way to create this, I
> think {get: getterFn, lazy: true, …} could work.
>
> Herby
>
> >        get: (value =>
> >          // still a getter
> >          () => value
> >        )(
> >          // executed once
> >          take(n - 1, xs.tail)
> >        )
> >      }).tail;
> >    }
> >};
> >```
> >
> >This would keep initial accessor configuration, in terms of
> >enumerability,
> >but it will freeze its value forever and, on top of that, this will
> >play
> >already well with current valid ES2015 classes syntax.
>
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to