<div dir="ltr">in case the counter proposal is not clear enough (apologies for that), this should read simpler than that<div><br></div><div>```js</div><div><div>const take = (n, xs) => n === 0 ? null : xs && {</div><div>    head: xs.head,</div><div>    lazy tail() {</div><div>      const value = take(n - 1, xs.tail);</div><div>      Object.defineProperty(this, 'tail', {</div><div>        configurable: false,</div><div>        get: () => value</div><div>      });</div><div>      return value;</div><div>    }</div><div>};</div></div><div>```</div><div><br></div><div>Hope it's clear what I'd change.</div><div><br></div><div>Best Regards</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jun 12, 2018 at 9:45 AM, Andrea Giammarchi <span dir="ltr"><<a href="mailto:andrea.giammarchi@gmail.com" target="_blank">andrea.giammarchi@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">* <span style="font-size:12.800000190734863px">having an extra keyword ...</span></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jun 12, 2018 at 9:44 AM, Andrea Giammarchi <span dir="ltr"><<a href="mailto:andrea.giammarchi@gmail.com" target="_blank">andrea.giammarchi@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">My 2 cents,<div>  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.<div><br></div><div><b>## Keep it get<i>ish</i></b></div><div><br></div><div>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.</div><div><br></div><div><b>## class compatible</b></div><div><br></div><div>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.</div><div><br></div><div>My variant would do the same, except it would keep the value an accessor:</div><div><br></div><div>```js</div><div><span><div>const take = (n, xs) => n === 0 ? null : xs && {</div><div>    head: xs.head,</div></span><div>    lazy tail() {</div><div>      return Object.defineProperty(this, 'tail', {</div><div>        configurable: false,</div><div>        get: (value =></div><div>          // still a getter</div><div>          () => value</div><div>        )(</div><div>          // executed once</div><div>          take(n - 1, xs.tail)</div><div>        )</div><div>      }).tail;</div><div>    }</div><div>};</div></div><div>```</div><div><br></div><div>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.</div><div><br></div><div>I also believe myself proposed something similar a while ago (or somebody else and I agreed with that proposal) but for some reason it never landed.</div><div><br></div><div>Hopefully this time the outcome would be different.</div><div><br></div><div>Best Regards</div><div><br></div><div><br></div><div><br></div></div></div><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="m_265198623809991052h5">On Tue, Jun 12, 2018 at 9:13 AM, Aadit M Shah <span dir="ltr"><<a href="mailto:aaditmshah@fastmail.fm" target="_blank">aaditmshah@fastmail.fm</a>></span> wrote:<br></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="m_265198623809991052h5"><u></u>





<div><div style="font-family:Georgia"><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336font" style="font-family:verdana,sans-serif,sans-serif">Hello TC39,</span><br></div>
<div style="font-family:Georgia"><br></div>
<div style="font-family:Georgia"><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336font" style="font-family:verdana,sans-serif,sans-serif">I recently <a href="https://github.com/tc39/ecma262/issues/1223" target="_blank">opened an issue</a> in the <a href="https://github.com/tc39/ecma262" target="_blank">tc39/ecma262</a> repository, proposing a new syntax for lazy getters, and I was directed to the <a href="https://github.com/tc39/ecma262/blob/master/CONTRIBUTING.md" target="_blank">CONTRIBUTING</a> page which stated that I should start a conversation on this mailing list.</span><br></div>
<div style="font-family:Georgia"><br></div>
<div style="font-family:Georgia"><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336font" style="font-family:verdana,sans-serif,sans-serif">So, my feature proposal is to have syntactic sugar for creating <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get#Smart_self-overwriting_lazy_getters" target="_blank">lazy getters</a>. 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:</span><br></div>
<div style="font-family:Georgia"><br></div>
<div style="font-family:Georgia"><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336font" style="font-family:menlo,consolas,monospace,sans-serif"><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(255,0,0)">const</span> <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(0,0,255)">take</span> <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(255,0,0)">=</span> (n, xs) <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(255,0,0)">=></span> n <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(255,0,0)">===</span> <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(0,0,255)">0</span> <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(255,0,0)">?</span> <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(0,0,255)">null</span> <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(255,0,0)">:</span> xs <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(255,0,0)">&&</span> {</span><br></div>
<div style="font-family:Georgia"><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336font" style="font-family:menlo,consolas,monospace,sans-serif">    head<span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(255,0,0)">:</span> xs.head,</span><br></div>
<div style="font-family:Georgia"><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336font" style="font-family:menlo,consolas,monospace,sans-serif">    <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(255,0,0)">get</span> <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(128,0,128)">tail</span>() {</span><br></div>
<div style="font-family:Georgia"><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336font" style="font-family:menlo,consolas,monospace,sans-serif">        <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(255,0,0)">delete</span> <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(0,0,255)">this</span>.tail;</span><br></div>
<div style="font-family:Georgia"><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336font" style="font-family:menlo,consolas,monospace,sans-serif">        <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(255,0,0)">return</span> <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(0,0,255)">this</span>.tail <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(255,0,0)">=</span> <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(128,0,128)">take</span>(n <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(255,0,0)">-</span> <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(0,0,255)">1</span>, xs.tail);</span><br></div>
<div style="font-family:Georgia"><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336font" style="font-family:menlo,consolas,monospace,sans-serif">    }</span><br></div>
<div style="font-family:Georgia"><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336font" style="font-family:menlo,consolas,monospace,sans-serif">};</span><br></div>
<div style="font-family:Georgia"><br></div>
<div style="font-family:Georgia"><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336font" style="font-family:verdana,sans-serif,sans-serif">My proposed solution is to add a new keyword </span><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336font" style="font-family:menlo,consolas,monospace,sans-serif"><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(255,0,0)">lazy</span></span><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336font" style="font-family:verdana,sans-serif,sans-serif"> 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:</span><br></div>
<div style="font-family:Georgia"><br></div>
<div style="font-family:Georgia"><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336font" style="font-family:menlo,consolas,monospace,sans-serif"><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(255,0,0)">const</span> <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(0,0,255)">take</span> <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(255,0,0)">=</span> (n, xs) <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(255,0,0)">=></span> n <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(255,0,0)">===</span> <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(0,0,255)">0</span> <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(255,0,0)">?</span> <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(0,0,255)">null</span> <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(255,0,0)">:</span> xs <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(255,0,0)">&&</span> {</span><br></div>
<div style="font-family:Georgia"><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336font" style="font-family:menlo,consolas,monospace,sans-serif">    head<span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(255,0,0)">:</span> xs.head,</span><br></div>
<div style="font-family:Georgia"><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336font" style="font-family:menlo,consolas,monospace,sans-serif">    <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(255,0,0)">lazy</span> tail<span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(255,0,0)">:</span> <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(128,0,128)">take</span>(n <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(255,0,0)">-</span> <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(0,0,255)">1</span>, xs.tail)</span><br></div>
<div style="font-family:Georgia"><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336font" style="font-family:menlo,consolas,monospace,sans-serif">};</span><br></div>
<div style="font-family:Georgia"><br></div>
<div style="font-family:Georgia"><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336font" style="font-family:verdana,sans-serif,sans-serif">This is purely syntactic sugar. The semantics of this new syntax would remain the same as that of the desugared syntax. In particular, calling </span><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336font" style="font-family:menlo,consolas,monospace,sans-serif"><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(0,0,255)">Object</span>.<span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(128,0,128)">getOwnPropertyDescripto<wbr>r</span>(list, <span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336colour" style="color:rgb(0,0,255)">"tail"</span>)</span><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336font" style="font-family:verdana,sans-serif,sans-serif"> would return an accessor descriptor before accessing </span><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336font" style="font-family:menlo,consolas,monospace,sans-serif">list.tail</span><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336font" style="font-family:verdana,sans-serif,sans-serif"> and a data descriptor afterwards.</span><br></div>
<div style="font-family:Georgia"><br></div>
<div style="font-family:Georgia"><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336font" style="font-family:verdana,sans-serif,sans-serif">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.</span><br></div>
<div style="font-family:Georgia"><br></div>
<div style="font-family:Georgia"><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336font" style="font-family:verdana,sans-serif,sans-serif">Regards,</span><br></div>
<div style="font-family:Georgia"><span class="m_265198623809991052m_7088313212853652715m_-2381812636088125336font" style="font-family:verdana,sans-serif,sans-serif">Aadit M Shah</span><br></div>
</div>

<br></div></div><span>______________________________<wbr>_________________<br>
es-discuss mailing list<br>
<a href="mailto:es-discuss@mozilla.org" target="_blank">es-discuss@mozilla.org</a><br>
<a href="https://mail.mozilla.org/listinfo/es-discuss" rel="noreferrer" target="_blank">https://mail.mozilla.org/listi<wbr>nfo/es-discuss</a><br>
<br></span></blockquote></div><br></div>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div>