<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Nov 11, 2015 at 7:34 AM, Tobias Pape <span dir="ltr">&lt;<a href="mailto:Das.Linux@gmx.de" target="_blank">Das.Linux@gmx.de</a>&gt;</span> wrote:<br><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">So, I&#39;d be more happy if we&#39;d name the temporary immutability &quot;write-locked&quot; or so, because a lock can be lifted, actual immutability is perpetual…<br>
I can live with a write-lock bit :D</blockquote><div><br></div><div>Yeah, I&#39;d like to see this too. I think there are 3 interesting cases here:<br></div><div><br></div><div><br></div><div>Write Barrier</div><div><br></div><div>This what VW (mistakenly) calls &quot;immutability&quot;. As Eliot described up thread, each object has a bit can be set to trap writes. When the bit is set, any primitive that modifies the object fails, and any bytecode that modifies the object instead se<font face="arial, helvetica, sans-serif">nds #</font><span style="font-size:12.8px"><font face="arial, helvetica, sans-serif">attemptToWrite:atIndex:. It lets writes be intercepted by image-level code, which is useful for external persistence mechanisms, eg Gemstone.</font></span></div><div><span style="font-size:12.8px"><font face="arial, helvetica, sans-serif"><br></font></span></div><div><span style="font-size:12.8px"><font face="arial, helvetica, sans-serif">An alternate implementation might be to just set a bit whenever a write operation occurs, and then have primitives for testing and clearing the bit explicitly. Persistence mechanisms tend to just want to know when an object has changed, and don&#39;t really need to intercept the change before it happens, so this would be sufficient. </font></span></div><div><span style="font-size:12.8px"><font face="arial, helvetica, sans-serif"><br></font></span></div><div><span style="font-size:12.8px"><font face="arial, helvetica, sans-serif"><br></font></span></div><div><span style="font-size:12.8px"><font face="arial, helvetica, sans-serif">Read Barrier</font></span></div><div><span style="font-size:12.8px"><font face="arial, helvetica, sans-serif"><br></font></span></div><div><span style="font-size:12.8px"><font face="arial, helvetica, sans-serif">Similar to the write barrier, but for reads. Again, I could imagine two ways of doing it. One would be to trap reads by sending something like #attemptToRead:atIndex: and then having the read complete with whatever that method returns. Another would be to set a bit on every read, and have primitives for testing and clearing it.</font></span></div><div><span style="font-size:12.8px"><font face="arial, helvetica, sans-serif"><br></font></span></div><div><span style="font-size:12.8px"><font face="arial, helvetica, sans-serif">Persistence code typically creates stub objects that &quot;fault&quot; when they receive a message, pull in data from outside the image, then become the appropriate object. Having a read barrier of the </font></span><span style="font-family:arial,helvetica,sans-serif;font-size:12.8px">#attemptToRead:atIndex: sort would let the object be created with the correct class, and then populated with state when it&#39;s actually needed. </span></div><div><span style="font-family:arial,helvetica,sans-serif;font-size:12.8px"><br></span></div><div><span style="font-family:arial,helvetica,sans-serif;font-size:12.8px">The other implementation with a bit that keeps track of which objects have been read would be useful for other cases. One example I ran into is in Altitude. Managing state is the essence of web applications, and getting good performance and scalability requires caching of state at several different levels of the system. One thing I was trying to do was generate ETag headers based on which model objects were read during the rendering of a particular resource, so that the ETag values would change iff the state of the model objects that affected the rendered data changed. </span></div><div><span style="font-family:arial,helvetica,sans-serif;font-size:12.8px"><br></span></div><div><span style="font-family:arial,helvetica,sans-serif;font-size:12.8px">One might do the same in the case of an IDE, for example. The visual state of a given browser window depends on the state of a certain set of objects in the image - classes, methods, organizers etc. By knowing *which* objects contributed to a given view, we can know that we have to update the view when, and only when, those objects change. </span></div><div><span style="font-family:arial,helvetica,sans-serif;font-size:12.8px"><br></span></div><div><span style="font-family:arial,helvetica,sans-serif;font-size:12.8px"><br></span></div><div><span style="font-family:arial,helvetica,sans-serif;font-size:12.8px">Immutability</span></div><div><span style="font-family:arial,helvetica,sans-serif;font-size:12.8px"><br></span></div><div><span style="font-family:arial,helvetica,sans-serif;font-size:12.8px">True immutability, not the VW version. I&#39;d like to see this implemented as a property of classes. Immutable classes create instances via a new primitive that instantiates and initializes the object in one step. After that, the object cannot be modified. Having that invariant would be useful both in the VM and in the image. </span></div><div><span style="font-family:arial,helvetica,sans-serif;font-size:12.8px"><br></span></div><div><font face="arial, helvetica, sans-serif"><span style="font-size:12.8px">In the VM, we&#39;d be free to take liberties with object identity. As Tobias mentioned we could have &quot;value&quot; object that get copied rather than passed as references whenever that makes sense. We might inline value objects within other objects to avoid chasing pointers. We might reorganize arrays of value objects into arrays of their individual fields where that would be useful for performance. The GC might merge all references to identical value objects during heap compaction.</span></font></div><div><font face="arial, helvetica, sans-serif"><span style="font-size:12.8px"><br></span></font></div><div><font face="arial, helvetica, sans-serif"><span style="font-size:12.8px">In the image, we could share value objects between processes without worrying about synchronization. We could copy them over the network to make remote messaging more efficient. Persistence frameworks could read and write clusters of value objects along with their owning entities, rather than faulting them in one at a time. </span></font></div><div><font face="arial, helvetica, sans-serif"><span style="font-size:12.8px"><br></span></font></div><div><font face="arial, helvetica, sans-serif"><span style="font-size:12.8px">Even for more prosaic applications, immutable objects are pretty useful. I find I often create pseudo-immutable classes, where the immutability isn&#39;t really enforced, but it happens that the only method that modifies an object&#39;s state is the initializer. Having that enforced by the VM would be create, and would let the image-level tools be smart about it as well. A browser might warn you if you accept a method that does a write on an immutable class.</span></font></div><div><font face="arial, helvetica, sans-serif"><span style="font-size:12.8px"><br></span></font></div><div><font face="arial, helvetica, sans-serif"><span style="font-size:12.8px"><br></span></font></div><div><font face="arial, helvetica, sans-serif"><span style="font-size:12.8px">Anyway, I&#39;m not trying to set the agenda for VM development, but could we please avoid Cincom&#39;s naming mistake and keep open the possibility of true immutability?</span></font></div><div><font face="arial, helvetica, sans-serif"><span style="font-size:12.8px"><br></span></font></div><div><font face="arial, helvetica, sans-serif"><span style="font-size:12.8px">-Colin</span></font></div></div></div></div>