[Proposal] New syntax for lazy getters

Aadit M Shah aaditmshah at fastmail.fm
Tue Jun 12 08:56:38 UTC 2018

When the getter lives on a prototype it would install the memoized value
on this using [[Define]]. This is the same way it would work in regular
lazy getters:
const defclass = prototype => {
    const constructor = prototype.constructor;
    constructor.prototype = prototype;
    return constructor;

const Person = defclass({
    constructor: function Person(firstname, lastname) {
        this.firstname = firstname;
        this.lastname  = lastname;
    lazy fullname: this.firstname + " " + this.lastname

const john = new Person("John", "Doe");
const jane = new Person("Jane", "Doe");

console.log(john.fullname); // John Doe
console.log(jane.fullname); // Jane Doe

Note that the this within the lazy property value expression (i.e.
within the expression this.firstname + " " + this.lastname) refers to
the instance (i.e. either john or jane). This can be confusing because
without the lazy keyword, this would refer to the lexical context.
Although I'm comfortable with it yet I'm open to other suggestions.

On Tue, Jun 12, 2018, at 3:31 AM, Jordan Harband wrote:
> How would this work when the getter lives on a prototype? (like most
> builtin getters) Would it install the memoized value on `this`, or on
> the object that contains the getter? Would it use [[Set]] or
> [[Define]]?> 
> On Tue, Jun 12, 2018 at 12:13 AM, Aadit M Shah
> <aaditmshah at fastmail.fm> wrote:>> __
>> Hello TC39,
>> I recently opened an issue[1] in the tc39/ecma262[2] repository,
>> proposing a new syntax for lazy getters, and I was directed to the
>> CONTRIBUTING[3] page which stated that I should start a conversation
>> on this mailing list.>> 
>> So, my feature proposal is to have syntactic sugar for creating lazy
>> getters[4]. To summarize my original proposal (which you can read by
>> following the very first link above), I find that creating lazy
>> getters is very verbose. For example, consider:>> 
>> const take = (n, xs) => n ===  ? null : xs && {
>>     head: xs.head,
>>     get tail() {
>>         delete this.tail;
>>         return this.tail = take(n - 1, xs.tail);
>>     }
>> };
>> My proposed solution is to add a new keyword lazy to the language.
>> This keyword can only be used as a prefix to longhand property names
>> in object initializers, and it defers the execution of the value
>> expression until the property is accessed. In short, it's just
>> syntactic sugar for lazy getters:>> 
>> const take = (n, xs) => n ===  ? null : xs && {
>>     head: xs.head,
>>     lazy tail: take(n - 1, xs.tail)
>> };
>> This is purely syntactic sugar. The semantics of this new syntax
>> would remain the same as that of the desugared syntax. In particular,
>> calling Object.getOwnPropertyDescriptor(list, "tail") would return an
>> accessor descriptor before accessing list.tail and a data descriptor
>> afterwards.>> 
>> Furthermore, there are other advantages of having this syntactic
>> sugar. For example, creating cyclic data structures becomes much
>> easier. Examples are provided in my original proposal which is linked
>> above. Hope to hear your thoughts on this.>> 
>> Regards,
>> Aadit M Shah
>> _______________________________________________
>>  es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss


  1. https://github.com/tc39/ecma262/issues/1223
  2. https://github.com/tc39/ecma262
  3. https://github.com/tc39/ecma262/blob/master/CONTRIBUTING.md
  4. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get#Smart_self-overwriting_lazy_getters
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20180612/17aff453/attachment.html>

More information about the es-discuss mailing list