<div dir="ltr"><div class="gmail_extra"><div style="font-family:arial,sans-serif;font-size:13px">The push below includes changes to letrec expressions, internal definitions, units, classes, and certain ill-formed shared expressions so that they no longer leak the `undefined' value. If a variable bound to the undefined value is referenced at runtime, an exception is raised. </div>
<div style="font-family:arial,sans-serif;font-size:13px"><br></div><div style="font-family:arial,sans-serif;font-size:13px">We are aware that these changes are not backwards compatible. We've deliberately put them in the development branch to get a sense of how much of a problem that is.</div>
<div style="font-family:arial,sans-serif;font-size:13px"><br></div><div style="font-family:arial,sans-serif;font-size:13px">Internal libraries that depend on having `undefined' as an initialization value now import the racket/unsafe/undefined library but should always keep it from leaking. The unsafe library provides the internal `unsafe-undefined' value and the internal function `check-not-unsafe-undefined' that errors if given the `unsafe-undefined' value but otherwise acts like the identity function. We extremely discourage the external use of racket/unsafe/undefined and it will not play nicely with anything that uses letrec.<br>
</div><div style="font-family:arial,sans-serif;font-size:13px"><br></div><div style="font-family:arial,sans-serif;font-size:13px">Programs that cannot be refactored to not use `undefined' should instead use the "better" undefined value from the racket/undefined collect. This `undefined' value can still leak out of shared expressions when using mutable pairs.</div>
<div style="font-family:arial,sans-serif;font-size:13px"><br></div><div style="font-family:arial,sans-serif;font-size:13px">For those interested in the implementation details:</div><div style="font-family:arial,sans-serif;font-size:13px">
- A new compiler pass wraps check-not-unsafe-undefined around any letrec-bound variable references that could possibly leak the undefined value. It runs a simple analysis to determine which variable references need such checks. From the benchmarks we've run, it looks like a relatively low number of variable references actually need checks. However, these checks do have the potential to disable certain optimizations such as inlining of variables with checked references.<br>
</div><div style="font-family:arial,sans-serif;font-size:13px">- The change to classes is more experimental. Any instance of a class that could possibly reference a field before it is assigned is chaperoned. The chaperone watches for a reference to the internal undefined value. The class macro performs its own analysis to determine which classes need to be chaperoned. <br>
</div><div style="font-family:arial,sans-serif;font-size:13px"><br></div><div style="font-family:arial,sans-serif;font-size:13px"><div>TL;DR you should not see unsafe-undefined ever again, but you may still see the "better" undefined when using (libraries that use) racket/undefined.</div>
<div><br></div></div><div style="font-family:arial,sans-serif;font-size:13px">Claire</div></div><div class="gmail_extra"><br></div><div class="gmail_extra"><br></div><div class="gmail_extra"><br></div><div class="gmail_extra">
On Tue, Apr 15, 2014 at 5:38 PM, <span dir="ltr"><<a href="mailto:mflatt@racket-lang.org" target="_blank">mflatt@racket-lang.org</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">
mflatt has updated `master' from 69984fb231 to a283f3d804.<br> <a href="http://git.racket-lang.org/plt/69984fb231..a283f3d804" target="_blank">http://git.racket-lang.org/plt/69984fb231..a283f3d804</a><br><br>=====[ 19 Commits ]=====================================================<br>
<br><br>~~~~~~~~~~<br><br>72c958d Claire Alvis <<a href="mailto:claire.alvis@gmail.com">claire.alvis@gmail.com</a>> 2013-05-07 09:36<br>:<br>| all necessary changes to check references to uninitialized letrec variables<br>
|<br>| includes a new pass, letrec_check, two new primitives, and<br>| changes to packages that grabbed the letrec undefined value</blockquote></div></div>