[racket-dev] Full transparency

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Thu Jan 22 07:36:18 EST 2015

I don't think you want to do anything with the compiler or macros.
Instead, it's a matter of having a sufficiently powerful inspector
(which is the concept of "inspectability" turned into a language
construct).

If you have just

 (struct a (x))
 (a 1)

then the result will print as `#<a>`. But if you use

 (define orig-i (current-inspector))
 (define sub-i (make-inspector orig-i))

 (current-inspector sub-i)
 (struct a (x))
 (define v (a 1))
 (current-inspector orig-i)

 v

Then, the result will print as `(a 1)`. That's because the structure
declaration is creates under an inspector `sub-i` (which is the current
inspector at the time) that is subordinate to the inspector `orig-i`
that is in place when the structure instance is printed.

The current inspector is determined dynamically, which means that if
you're loading some code, you can set the inspector while loading the
code. For example, if "a.rkt" is

 #lang racket/base
 (provide v)

 (struct a (x))
 (define v (a 1))

then

 (define v
   (parameterize ([current-inspector (make-inspector)])
     (dynamic-require "a.rkt" 'v)))
 v

will print the `a` instance transparently.


To protect libraries, there's no safe way to access a root inspector
that controls all structure types when you start Racket. Nothing is
safe from unsafe code, though, and here's an unsafe way to access the
root inspector:

 #lang racket/base
 (require ffi/unsafe)

 (define-cstruct _Scheme_Inspector
   ([stag _short]
    [keyex _short]
    [depth _int]
    [superior _racket]))

 (define root-inspector
   (Scheme_Inspector-superior
    ((get-ffi-obj 'scheme_get_initial_inspector
                  #f
                  (_fun -> (_gcable _Scheme_Inspector-pointer))))))

Using `root-inspector`, you can inspect any structure instance.

At Wed, 21 Jan 2015 23:46:10 -0700, Byron Davies wrote:
> Nice parry!  What may be straightforward to you may not be so obvious to
> me.  But I'll take a look.
> 
> I'm deep into a project using Racket for weakest precondition analysis.
> Every time I'm debugging it seems like I have to write another
> special-purpose accessor, or export some existing accessor up through
> multiple levels in order to get at the data I need at the top-level.  I
> remember how easy it was with the Lisp Machine to navigate through data no
> matter what it was.
> 
> The Lisp Machine offered total transparency, with no real way to protect
> data, to the benefit of the developer.  Racket offers total opacity, to the
> benefit of code security.  I'm hoping there's a middle ground, where
> transparency can be turned on and off.
> 
> Byron
> 
> On Wed, Jan 21, 2015 at 12:20 PM, Matthias Felleisen <matthias at ccs.neu.edu>
> wrote:
> 
> >
> > Sounds like a straightforward change to the existing macros. Why don't you
> > create a fork and experiment?
> >
> >
> > On Jan 21, 2015, at 1:15 PM, Byron Davies <byrondavies at starshine.us>
> > wrote:
> >
> > > Or, more conservatively, every struct and object in a given package,
> > file, or set of files.
> > >
> > > On Wed, Jan 21, 2015 at 11:03 AM, Byron Davies <byrondavies at starshine.us>
> > wrote:
> > > Would it be easy to create a compiler flag that would make every struct
> > and object transparent?  This would then make it easy to create a Lisp
> > Machine-style Inspector that would be able to roam through every data
> > structure during debugging.
> > >
> > > Byron
> > >
> > >
> > > _________________________
> > >  Racket Developers list:
> > >  http://lists.racket-lang.org/dev
> >
> >
> _________________________
>   Racket Developers list:
>   http://lists.racket-lang.org/dev

Posted on the dev mailing list.