>>>>> Duncan Murdoch >>>>> on Mon, 26 Aug 2019 14:19:36 -0400 writes:
> On 26/08/2019 1:58 p.m., William Dunlap wrote: >> Duncan Murdoch wrote: >> > Scripts are for throwaways, not for anything worth keeping. >> >> I totally agree and have a tangentially relevant question about the <<- >> operator. Currently 'name <<- value' means to look up the environment >> stack until you find 'name' and (a) if you find 'name' in some frame >> bind it to a new value in that frame and (b) if you do not find it make >> a new entry for it in .GlobalEnv. >> >> Should R deprecate the second part of that and give an error if 'name' >> is not already present in the environment stack? This would catch >> misspelling errors in functions that collect results from recursive >> calls. E.g., > I like that suggestion. Package tests have been complaining about > packages writing to .GlobalEnv for a while now, so there probably aren't > many instances of b) in CRAN packages; that change might be relatively > painless. > Duncan Murdoch I don't agree currently : AFAICS, there's no other case (in S or) R where an assignment only works if there's no object with that name. In addition: If I wanted such a functionality I'd rather have with a function that has several arguments and this behavior was switchable via <argname> = TRUE/FALSE , rather than with `<<-` which has always exactly 2 arguments. [This is my personal opinion only; other R Core members may well think differently about this] Martin >> collectStrings <- function(list) { >> strings <- character() # to be populated by .collect >> .collect <- function(x) { >> if (is.list(x)) { >> lapply(x, .collect) >> } else if (is.character(x)) { >> strings <<- c(strings, x) >> } >> misspelledStrings <<- c(strings, names(x)) # oops, would like >> to be told about this error >> NULL >> } >> .collect(list) >> strings >> } >> >> This gives the incorrect: >> > collectStrings(list(i="One", ii=list(a=1, b="Two"))) >> [1] "One" "Two" >> > misspelledStrings >> [1] "One" "Two" "i" "ii" >> >> instead of what we would get if 'misspelledStrings' were 'strings'. >> > collectStrings(list(i="One", ii=list(a=1, b="Two"))) >> [1] "One" "Two" "a" "b" "i" "ii" >> >> If someone really wanted to assign into .GlobalEnv the assign() function >> is available. >> >> In S '<<-' only had meaning (b) and R added meaning (a). Perhaps it is >> time to drop meaning (b). We could start by triggering a warning about >> it if some environment variable were set, as is being done for >> non-scalar && and ||. >> >> Bill Dunlap >> TIBCO Software >> wdunlap tibco.com <http://tibco.com> >> >> >> On Sun, Aug 25, 2019 at 5:09 PM Duncan Murdoch <murdoch.dun...@gmail.com >> <mailto:murdoch.dun...@gmail.com>> wrote: >> >> On 25/08/2019 7:09 p.m., Cyclic Group Z_1 wrote: >> > >> > >> > This is a fair point; structuring functions into packages is >> probably ultimately the gold standard for code organization in R. >> However, lexical scoping in R is really not much different than in >> other languages, such as Python, in which use of main functions and >> defining other named functions outside of main are encouraged. For >> example, in Scheme, from which R derives its scoping rules, the >> community generally organizes code with almost exclusively functions >> and few non-function global variables at top level. The common use >> of globals in R seems to be mostly a consequence of historical >> interactive use and, relatedly, an inherited practice from S. >> > >> > It is true, though, that since anonymous functions (such as in >> lapply) play a large part in idiomatic R code, as you put it, >> "[l]exical scoping means that all of the problems of global >> variables are available to writers who use main()." Nevertheless, >> using a main function with other functions defined outside it seems >> like a good quick alternative that offers similar advantages to >> making a package when functions are tightly coupled to the script >> and the project may not be large or generalizable enough to warrant >> making a package. >> > >> >> I think the idea that making a package is too hard is just wrong. >> Packages in R have lots of requirements, but nowadays there are tools >> that make them easy. Eleven years ago at UseR in Dortmund I wrote a >> package during a 45 minute presentation, and things are much easier now. >> >> If you make a complex project without putting most of the code into a >> package, you don't have something that you will be able to modify in a >> year or two, because you won't have proper documentation. >> >> Scripts are for throwaways, not for anything worth keeping. >> >> Duncan Murdoch >> >> ______________________________________________ >> R-devel@r-project.org <mailto:R-devel@r-project.org> mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel >> > ______________________________________________ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel