[Rd] attributes on symbols

Tomas Kalibera tomas.kalibera at gmail.com
Fri Aug 11 11:46:03 CEST 2017


Thanks for spotting this issue. The short answer is yes, adding 
attributes to a symbol is a bad idea and will be turned into a runtime 
error soon. Maintainers of packages that add attributes to symbols have 
been notified and some have already fixed their code.

At least in one case the package is not working properly, even in 
isolation, because of the global effect of adding an attribute to a 
symbol. Think about an expression "x - x", adding sign 1 to the "first 
x" and then sign -1 to the "second x" ends up with (both) "x" having 
sign "-1", because it is the same "x". The package would need something 
like a symbol, but passed by value (suggestions below).

By design in R symbols are represented by singleton objects registered 
in a global symbol table. Symbols are passed by reference and are fully 
represented by their name or pointer, so they can be quickly compared by 
pointer comparison and they can be used for bindings (naming variables, 
functions). Symbols thus cannot have attributes attached and must be 
treated as immutable. For this reason also attributes on symbols are not 
preserved on serialization (as Radford pointed out).

In some cases one needs to add an attribute to something similar to a 
symbol, but something passed by value. There are multiple ways to do it 
(credits for suggestions to Peter, Michael and others):

- wrap a symbol into an object passed by value, add an attribute to that 
object; such an object can be a list, an S3 or S4 object, an expression, 
etc; in "x - x", there will be two different wrappers of "x"

- encapsulate a symbol and needed meta-data (what would be in the 
attribute) together into an object passed by value, e.g. into S3/S4 
object or a list; in "x - x", there will again be two different objects 
encapsulating "x"

- store the meta-data (what would be in the attribute) in a user 
environment created by new.env(); the meta-data could be conveniently 
looked up by the symbol and the environment can be hashed for fast 
lookup; from Peter:
> attrib <- new.env()
> attributes(sym) ----> attrib$sym
> attr(sym, "foo") ----> attrib$sym[["foo"]]
(the last suggestion will not work for the example "x-x", but may work 
for other where referential semantics is needed, but now in a well 
defined scope)


Best,
Tomas


On 07/07/2017 03:06 PM, Torsten Hothorn wrote:
>
> Here is a simpler example:
>
>> ex <- as.name("a")
>> attr(ex, "test") <- 1
>> quote(a)
> a
> attr(,"test")
> [1] 1
>
> Torsten
>
> On Thu, 6 Jul 2017, William Dunlap wrote:
>
>> The multcomp package has code in multcomp:::expression2coef that 
>> attaches the 'coef' attribute to
>> symbols.  Since there is only one symbol object in a session with a 
>> given name, this means that
>> this attaching has a global effect.  Should this be quietly allowed 
>> or should there be a warning or
>> an error?
>> E.g.,
>>
>> str(quote(Education))
>> # symbol Education
>> lmod <- stats::lm(Fertility ~ ., data = datasets::swiss)
>> glmod <- multcomp::glht(lmod, c("Agriculture=0", "Education=0"))
>> str(quote(Education))
>> # symbol Education
>> # - attr(*, "coef")= num 1
>>
>> Bill Dunlap
>> TIBCO Software
>> wdunlap tibco.com
>>
>>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel



More information about the R-devel mailing list