<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 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>