[racket-dev] Catching the undefined value

From: claire alvis (claire.alvis at gmail.com)
Date: Tue Apr 15 18:13:31 EDT 2014

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.

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.

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.

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.

For those interested in the implementation details:
- 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.
- 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.

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.

Claire



On Tue, Apr 15, 2014 at 5:38 PM, <mflatt at racket-lang.org> wrote:

> mflatt has updated `master' from 69984fb231 to a283f3d804.
>   http://git.racket-lang.org/plt/69984fb231..a283f3d804
>
> =====[ 19 Commits ]=====================================================
>
>
> ~~~~~~~~~~
>
> 72c958d Claire Alvis <claire.alvis at gmail.com> 2013-05-07 09:36
> :
> | all necessary changes to check references to uninitialized letrec
> variables
> |
> | includes a new pass, letrec_check, two new primitives, and
> | changes to packages that grabbed the letrec undefined value
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/dev/archive/attachments/20140415/a3717bb3/attachment.html>

Posted on the dev mailing list.