<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Oct 17, 2013 at 3:09 PM, Rafael Weinstein <span dir="ltr"><<a href="mailto:rafaelw@google.com" target="_blank">rafaelw@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><span style="font-family:arial,sans-serif;font-size:12.727272033691406px">At the September meeting, the committee discussed Object.observe. Below is a summary of the feedback, along with proposed changes to the spec.</span><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">

<br></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px"><br></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">1) Inconsistent naming of changeRecord types<br></div>
<div style="font-family:arial,sans-serif;font-size:12.727272033691406px">
<br></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">The spec currently defines the following types: 'new', 'updated', 'deleted', 'reconfigured', 'prototype' & 'splice',</div>

<div style="font-family:arial,sans-serif;font-size:12.727272033691406px"><br></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">Proposed change: Make changeRecord types all be present tense:  'add', 'update', 'delete', 'reconfigure', 'setPrototype', 'splice'</div>

<div style="font-family:arial,sans-serif;font-size:12.727272033691406px"><br></div><div style="font-size:12.727272033691406px;font-family:arial,sans-serif"><br></div><div style="font-size:12.727272033691406px;font-family:arial,sans-serif">

2) An object becoming non-extensible isn't observable<br></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px"><br></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">

Proposed change: Add a 'preventExtensions' type.</div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px"><br></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px"><div>

<br></div><div>3) Concern about namespace collisions of future change type.<br></div></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px"><br></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">

Proposed change: None. Adding an explicit namespace to changeRecords is overkill. Future objects will simply need to ensure that added type names are unique.</div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">

<br></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px"><br></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">4) notifier.performChange should allow a returned object from its changeFn to be used as the notification object. E.g.</div>

<div style="font-family:arial,sans-serif;font-size:12.727272033691406px"><br></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px"><div>  notifier.performChange('embiggened', () => {</div>

<div>    this.width *= amount;</div><div>    this.height *= amount;</div><div><br></div><div>    return {</div><div>      amount: amount</div><div>    };</div><div>  });</div></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">

<br></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">as short hand for </div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px"><br></div><div><div><font face="arial, sans-serif">embiggin: function(int amount) {</font></div>

<div><font face="arial, sans-serif">  notifier.performChange('embiggened', () => {</font></div><div><font face="arial, sans-serif">    this.width *= amount;</font></div><div><font face="arial, sans-serif">    this.height *= amount;</font></div>

<div><font face="arial, sans-serif">  });</font></div><div><font face="arial, sans-serif"><br></font></div><div><font face="arial, sans-serif">  notifier.notify({</font></div><div><font face="arial, sans-serif">    type: 'embiggened',</font></div>

<div><font face="arial, sans-serif">    amount: amount</font></div><div><font face="arial, sans-serif">  });</font></div><div><font face="arial, sans-serif">}</font></div></div></div></blockquote><div><br></div><div>copy/paste error. This should have been:</div>
<div><br></div><div>as short hand for:</div><div><br></div><div>  notifier.performChange('embiggened', () => {</div><div>    this.width *= amount;</div><div>    this.height *= amount;</div><div>  });</div><div>
<br></div><div>  notifier.notify({</div><div>    type: 'embiggened',</div><div>    amount: amount</div><div>  });</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div dir="ltr"><div><div><font face="arial, sans-serif"> </font></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">
<br></div></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">Proposed change: Support this. If the return value of the changeFn is an object, then emit a notification on the notifier's |target| with the same type as that used for the performChange.</div>

<div style="font-family:arial,sans-serif;font-size:12.727272033691406px"><br></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px"><br></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">

5) If a changeFn provided to performChange throws before completion, an observer who accepts the performed change type won't get precise information about which parts of the modification succeeded.</div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">

<br></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">Proposed Change: None. The concern here about fault tolerance here is valid. The problem is that a central motivation of the performChange mechanism is performance, and the solution to this problem negates the main performance benefit -- the ability in common cases to avoid the accounting costs of generating the information for the lower-level changes. IOW, in order to have failure result in the higher-level observer hearing about the succeeded portion of the lower-level mutations, the system will have to incur much of the cost of generating these records in all cases.</div>

<div style="font-family:arial,sans-serif;font-size:12.727272033691406px"><br></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">The bright spot here is that the success criteria that Mark proposed still likely holds in that if a full mirror is maintained via observation, and operations are deterministic, then the failure will occur on both sides in the same way and the two sides will stay in sync.</div>

<div style="font-family:arial,sans-serif;font-size:12.727272033691406px"><br></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px"><br></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">

6) Object.observe(obj, callback, opt_acceptList) implements a JS antipattern: the callback argument isn't in the final position.</div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px"><br></div>

<div style="font-family:arial,sans-serif;font-size:12.727272033691406px">Proposed change: None. Use of the final argument will be *extremely* rare. It's mostly there so that domain objects can expose custom observe methods which specify the correct accept types, e.g.</div>

<div style="font-family:arial,sans-serif;font-size:12.727272033691406px"><br></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">Array.observe =~ function(object, callback) {</div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">

  return Object.observe(object, callback, ['add', 'update', 'delete', 'splice'])</div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">}</div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">

<br></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">There are three possible solutions to this concern: (1) make callback the final argument, (2) Object.observe should take an arguments object, and (3) Have Object.observe type check the second argument looking for either a function or an array (support implicit multiple call signatures).</div>

<div style="font-family:arial,sans-serif;font-size:12.727272033691406px"><br></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">I'm interested in other's thoughts on this, but given the likely rarity of providing the final argument, none of these seems like an improvement.</div>

<div style="font-family:arial,sans-serif;font-size:12.727272033691406px"><br></div></div>
</blockquote></div><br></div></div>