From m@ech|er @end|ng |rom @t@t@m@th@ethz@ch  Tue Aug 27 11:36:32 2019
From: m@ech|er @end|ng |rom @t@t@m@th@ethz@ch (Martin Maechler)
Date: Tue, 27 Aug 2019 11:36:32 +0200
Subject: [Rd] Conventions: Use of globals and main functions
In-Reply-To: <ab5d1ccd-b971-4403-e328-db9bb3b23ec5@gmail.com>
References: <1118624909.2128031.1566706119596.ref@mail.yahoo.com>
 <1118624909.2128031.1566706119596@mail.yahoo.com>
 <551feaef-9cf1-91d5-ff4a-0eeb36328bab@gmail.com>
 <1278224074.2337376.1566774597756@mail.yahoo.com>
 <739a44fe-4fd4-ee75-cf93-ea32d8760de7@gmail.com>
 <CAF8bMcaU2ycRd7YA1ziZeoVyZ24uY1fTmV9131pbp2p3uM_qVQ@mail.gmail.com>
 <ab5d1ccd-b971-4403-e328-db9bb3b23ec5@gmail.com>
Message-ID: <23908.63904.114202.449706@stat.math.ethz.ch>

>>>>> 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.duncan at gmail.com 
    >> <mailto:murdoch.duncan at 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 at r-project.org <mailto:R-devel at r-project.org> mailing list
    >> https://stat.ethz.ch/mailman/listinfo/r-devel
    >> 

    > ______________________________________________
    > R-devel at r-project.org mailing list
    > https://stat.ethz.ch/mailman/listinfo/r-devel



[Rd] Conventions: Use of globals and main functions
Martin Maechler