[Rd] attributes on symbols
lionel at rstudio.com
Fri Aug 11 12:00:40 CEST 2017
It's probably better to make it a runtime error, but note that it's
not necessarily a bad idea to add attributes to singleton symbols.
Those are used in Emacs Lisp for a variety of purposes. They just need
strong conventions (part of that is that in Emacs many symbols are
prefixed with a "namespace" identifier).
> On 11 août 2017, at 11:46, Tomas Kalibera <tomas.kalibera at gmail.com> wrote:
> 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)
> On 07/07/2017 03:06 PM, Torsten Hothorn wrote:
>> Here is a simpler example:
>>> ex <- as.name("a")
>>> attr(ex, "test") <- 1
>>  1
>> 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?
>>> # symbol Education
>>> lmod <- stats::lm(Fertility ~ ., data = datasets::swiss)
>>> glmod <- multcomp::glht(lmod, c("Agriculture=0", "Education=0"))
>>> # symbol Education
>>> # - attr(*, "coef")= num 1
>>> Bill Dunlap
>>> TIBCO Software
>>> wdunlap tibco.com
>> R-devel at r-project.org mailing list
> R-devel at r-project.org mailing list
More information about the R-devel