<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr">Hi Chris,</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Mar 11, 2020 at 4:03 PM Chris Muller <<a href="mailto:asqueaker@gmail.com">asqueaker@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr">Hi Eliot,<div></div><div><br></div><div></div><div>Can  ModificationForbidden be resumed?  I certainly hope so.  </div></div></div></blockquote><div><br></div><div>Indeed its can.  Use in database write barriers is one major use case.  However, the framework for convenient use has yet to be designed and implemented.  We have lots of experience with this barrier in VisualWorks and some experience in Pharo, so designing the right support should not be hard at all.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div>Magma's own WriteBarrier has one place where it dynamically compiles a literal in a method for the sole purpose of providing one extra reference slot needed for the framework.  This is a useful feature in a general sense, something I'd hate to see lost.  Yes, I understand it's "bad code" to modify a literal, just like using "become:" (which it also uses), but for frameworks that need to work slightly under the hood, these hacks can be very useful when one knows what they're doing.</div></div></div></blockquote><div><br></div><div>If you *do* have to modify a literal, then all you have to do is send beWritableObject to the literal in question and you'll be able to modify it (there is no recursive protection against setting read-only objects to writable).</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div>Unfortunately, I don't think the VM-based WriteBarrier can work for Magma due to its "global" nature.<br></div></div></div></blockquote><div><br></div><div>I'm willing to bet you that it can.  For example,e, it works in Gemstone on VisualWorks.  The solution is to provide a policy registry hat on a per-object basis specifies how modifications to objects are to be handled.  This registry typically/best exists in the exception class (ModificationForbidden), and maps an object to a MessageSend or block.  This registry tags specific instances with a retry policy, so e.g. Magma can put all objects it fetches from the database that it wants to be write-through into the registry and sets them to be read-only.  Then on an attempted modification the ModificationForbidden exception looks up the object in the registry, and if its there runs whatever code the registry specifies.  This would be some method in Magma that would</div><div>- set the object as writable</div><div>- ask the exception to retry the modification</div><div>- write the changed object through to the database</div><div>- set the object back to read-only</div><div>- resume the exception with a suitable value</div><div><br></div><div>Specific classes might implement a message the exception could send rather than require the registry is used.  But that's a space-saving optimization.</div><div><br></div><div>Such a framework allows several orthogonal clients to share the framework, potentially on the same objects because the registry can be engineered to have more than one action per object.</div><div><br></div><div>(BTW, this is how VisualWorks does things, IIRC)</div><div><br></div><div>Does that instill more confidence?</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div>When we added read-only object support to VisualWorks some of the engineering staff were of the opinion that insulating customers from the change was a necessary thing, and so we implemented a preference to allow automatic mutating of read-only literals so that customers whose code did modify literals could set the preference rather than fix their code.  I *really* don't ant to do this.  It is a lot of complication for little gain; the right fix is just to rewrite the code not to write to literals.  Note that that's as easy as:</div></div></div></div></div></div></blockquote><div><br></div><div></div><div>I don't think we need a global preference as much as just let it be #isResumable.  Can we do that?</div></div></div></blockquote><div><br></div><div>Yes, it is, but doing so loses the modification:</div><div><br></div><div><div>| l |</div><div>[(l := #(1 2 3)) at: 2 put: 'nevermore']</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>on: ModificationForbidden</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">      </span>do: [:ex| ex resume].</div><div>l => #(1 2 3)</div></div><div><br></div><div>whereas one often wants to do something more like this:</div><div><br></div><div><div>| lit result |</div><div>result := [(lit := #(1 2 3)) at: 2 put: 'nevermore']</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">    </span>on: ModificationForbidden</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">      </span>do: [:ex| ex object beWritableObject. ex retryModification].</div><div>lit -> result #(1 'nevermore' 3)->'nevermore'</div></div><div><br></div></div><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div></div></div></div></div>