Skip to content
Prev 388 / 12125 Next

[R-pkg-devel] Visible bindings and reference classes

On Tue, 11 Aug 2015, William Dunlap wrote:

            
Short answer: this isn't actually what is happening in Colin's
example, and in any case the notes seem OK to me, given what is
happening.

For the long answer, the basic issue is that the compiler, and
codetools, look at the code as it is written and try to make sense of
it. The methods implementation, and reference class implementation in
particular, rewrite the code in various ways. This creates some
mismatches. These can either we worked around by adapting
compiler/codetools to internals of methods/reference classes, or by
modifying methods/reference class implementations to be more amenable
to static analysis, or some combination.

The way packages are compiled already does adapt to the implementation
of methods/reference classes/etc to some degree by the way it compiles
code. It does not compile at the file level. Instead it compiles while
serializing code that has been loaded and in some cases modified by
the methods infrastructure, which is why the expression/file compile
example isn't related to what Colin was seeing. A reference class
definition like this at package top level should not be a problem for
byte compilation.

Here is a slight modification of Colin's example:

d1 = setRefClass("d1", fields=list(x = "numeric"))
a <- d1$accessors("x")

Then
function () 
x
<environment: 0x103c7e1f8>

and the environment of this function does not contain "x":
<anonymous>: no visible binding for global variable ?x?

When a packages using accessors is byte compiled the compiler sees
these incomplete accessor functions and points this out.

For an instance,
Class method definition for method getX()
function () 
x
<environment: 0x103ae3378>

This function has a new environment, the .xData part of v, and that does contain "x":
# no note

So a change to the implementation of the accessors method to create
its accessors with an environment that is like the one they would see
when the are used would remove this note. I'm happy to help but
someone more familiar with reference class internals would have to
take the lead on this.

Compiled functions revert to interpreted when their environments are
changed, so the code does work, but doesn't benefit from compilation.
This is a bit overly cautious: if the structure of the environments in
terms of the variables they define remains the same, as it would if
the accessors created in the class had environments that matched their
intended usage, then the compiled code would remain valid and could
still be used. [Of course at present there isn't much if any benefit
to compiling functions this small, but that may change in the future.]