The documentation for assignment says: In all the assignment operator expressions, 'x' can be a name or an expression defining a part of an object to be replaced (e.g., 'z[[1]]'). A syntactic name does not need to be quoted, though it can be (preferably by backticks). But the implementation allows assignment to a character string (i.e. not a name), which it coerces to a name: "foo" <- 23; foo # returns 23 > is.name("foo") [1] FALSE Is this a documentation error or an implementation error? The coercion is not happening at parse time: class(quote("foo"<-3)[[2]]) [1] "character" In fact, bizarrely, not only does it coerce to a name, it actually *modifies* the parse tree: > gg <- quote("hij" <- 4) > gg "hij" <- 4 > eval(gg) > gg hij <- 4 *** The cases below only come up with expression trees generated programmatically as far as I know, so are much more marginal cases. *** The <- operator even allows the left-hand-side to be of length > 1, though it just ignores the other elements, with the same side effect as before: > gg <- quote(x<-44) > gg[[2]] <- c("x","y") > gg c("x", "y") <- 44 > eval(gg) > x [1] 44 > y Error: object "y" not found > gg x <- 44 None of this is documented in ? <-, and it is rather a surprise that evaluating an expression tree can modify it. I admit we had a feature (performance hack) like this in MacLisp years ago, where expanded syntax macros replaced the source code of the macro, but it was a documented, general, and optional part of the macro mechanism. Another little glitch: gg <- quote(x<-44); gg[[2]] <- character(0); eval(gg) Error in eval(expr, envir, enclos) : 'getEncChar' must be called on a CHARSXP This looks like an internal error that users shouldn't see. -s [[alternative HTML version deleted]]
On Apr 1, 2009, at 15:49 , Stavros Macrakis wrote:> The documentation for assignment says: > > In all the assignment operator expressions, 'x' can be a name or > an expression defining a part of an object to be replaced (e.g., > 'z[[1]]'). A syntactic name does not need to be quoted, though it > can be (preferably by backticks). > > But the implementation allows assignment to a character string (i.e. > not a > name), which it coerces to a name: > > "foo" <- 23; foo > # returns 23 >> is.name("foo") > [1] FALSE > > Is this a documentation error or an implementation error? >Neither - what you're missing is that you are actually quoting foo namely with double-quotes. Hence both the documentation and the implementations are correct. (Technically "name" as referred above can be either a symbol or a character string). Cheers, Simon> The coercion is not happening at parse time: > > class(quote("foo"<-3)[[2]]) > [1] "character" > > In fact, bizarrely, not only does it coerce to a name, it actually > *modifies* the parse tree: > >> gg <- quote("hij" <- 4) >> gg > "hij" <- 4 >> eval(gg) >> gg > hij <- 4 > > *** The cases below only come up with expression trees generated > programmatically as far as I know, so are much more marginal cases. > *** > > The <- operator even allows the left-hand-side to be of length > 1, > though > it just ignores the other elements, with the same side effect as > before: > >> gg <- quote(x<-44) >> gg[[2]] <- c("x","y") >> gg > c("x", "y") <- 44 >> eval(gg) >> x > [1] 44 >> y > Error: object "y" not found >> gg > x <- 44 > > None of this is documented in ? <-, and it is rather a surprise that > evaluating an expression tree can modify it. I admit we had a feature > (performance hack) like this in MacLisp years ago, where expanded > syntax > macros replaced the source code of the macro, but it was a documented, > general, and optional part of the macro mechanism. > > Another little glitch: > > gg <- quote(x<-44); gg[[2]] <- character(0); eval(gg) > Error in eval(expr, envir, enclos) : > 'getEncChar' must be called on a CHARSXP > > This looks like an internal error that users shouldn't see. > > -s > > [[alternative HTML version deleted]] > > ______________________________________________ > R-devel at r-project.org mailing list > stat.ethz.ch/mailman/listinfo/r-devel > >
Stavros Macrakis wrote:> The documentation for assignment says: > > In all the assignment operator expressions, 'x' can be a name or > an expression defining a part of an object to be replaced (e.g., > 'z[[1]]'). A syntactic name does not need to be quoted, though it > can be (preferably by backticks). > > But the implementation allows assignment to a character string (i.e. not a > name), which it coerces to a name: > > "foo" <- 23; foo > # returns 23 > > is.name("foo") > [1] FALSE > > Is this a documentation error or an implementation error? >i think this concords with the documentation in the sense that in an assignment a string can work as a name. note that `foo bar` = 1 is.name(`foo`) # FALSE the issue is different here in that in is.name("foo") "foo" evaluates to a string (it works as a string literal), while in is.name(`foo`) `foo` evaluates to the value of the variable named 'foo' (with the quotes *not* belonging to the name). with only a quick look at the sources (src/main/envir.c:1511), i guess the first element to an assignment operator (i mean the left-assignment operators) is converted to a name, so that in "foo" <- 1 "foo" evaluates to a string and not a name (hence is.name("foo") is false), but internally it is sort of 'coerced' to a name, as in as.name("foo") # `foo` is.name(as.name("foo")) # TRUE> The coercion is not happening at parse time: > > class(quote("foo"<-3)[[2]]) > [1] "character" >i think the internal assignment op really receives a string in a case like "foo" <- 1, it knows it has to treat it as a name without the parser classifying the string as a name. (pure guesswork, again.) the documentation might avoid calling a plain string a 'quoted name', though, it is confusing. a quoted name is something like quote(name) or quote(`name`): is(quote(name)) # "name" "language" is(quote(`name`)) # "name" "language" but *not* something like "name": is("name") # "character" "vector" "data.frameRowLabels" and *not* like quote("name"): is(quote("name")) # "character" "vector" "data.frameRowLabels"> In fact, bizarrely, not only does it coerce to a name, it actually > *modifies* the parse tree: > > > gg <- quote("hij" <- 4) > > gg > "hij" <- 4 > > eval(gg) > > gg > hij <- 4 >wow! that's called 'functional programming' ;) you're right: gg = quote({"a" = 1}) is(gg[[2]][[2]]) # "character" ... eval(gg) is(gg[[2]][[2]]) # "name" ...> *** The cases below only come up with expression trees generated > programmatically as far as I know, so are much more marginal cases. *** > > The <- operator even allows the left-hand-side to be of length > 1, though > it just ignores the other elements, with the same side effect as before: >that's clear from the sources; see src/main/envir.c:1521. it should be documented (maybe it is, i haven't investigated this issue).> > gg <- quote(x<-44) > > gg[[2]] <- c("x","y") > > gg > c("x", "y") <- 44 > > eval(gg)but also this: rm(list=ls()) do.call('=', list(letters, 1)) # just fine a # 1 b # error weird these work. i think it deserves a warning, at the very least, as in c('x', 'y') = 4 # error: assignment to non-language object c(x, y) = 4 # error: could not find function c<- (provided that x and y are already there) btw., that's what you can do with rvalues (using the otherwise semantically void operator `:=`). these could seem equivalent, but they're (obviously) not: 'x' = 1 c('x') = 1 x = 1 c(x) = 1> > x > [1] 44 > > y > Error: object "y" not found > > gg > x <- 44 > > None of this is documented in ? <-, and it is rather a surprise that > evaluating an expression tree can modify it. I admit we had a feature > (performance hack) like this in MacLisp years ago, where expanded syntax > macros replaced the source code of the macro, but it was a documented, > general, and optional part of the macro mechanism. >but - maclisp was designed by computer scientists in a research project, - r is being implemented by statisticians for practical purposes. almost every part differs here (and almost no pun intended).> Another little glitch: > > gg <- quote(x<-44); gg[[2]] <- character(0); eval(gg) > Error in eval(expr, envir, enclos) : > 'getEncChar' must be called on a CHARSXP > > This looks like an internal error that users shouldn't see. >by no means the only example that the interface is no blood-brain barrier. vQ
Apparently Analagous Threads
- Samba 4.1.6-Ubuntu on 14.04 domain join seems successful with caveats, testjoin reports no logon servers...
- Samba 4.1.6-Ubuntu on 14.04 domain join seems successful with caveats, testjoin reports no logon servers...
- Samba 4.1.6-Ubuntu on 14.04 domain join seems successful with caveats, testjoin reports no logon servers...
- Internal error in 'ls' for pathological environments (PR#14035)
- read.table, NA assignment, and sep