From retep@me|@@ner @end|ng |rom gm@||@com  Wed Aug 28 09:24:43 2019
From: retep@me|@@ner @end|ng |rom gm@||@com (Peter Meissner)
Date: Wed, 28 Aug 2019 09:24:43 +0200
Subject: [Rd] Conventions: Use of globals and main functions
In-Reply-To: <1044532211.3694234.1566964607709@mail.yahoo.com>
References: <1118624909.2128031.1566706119596.ref@mail.yahoo.com>
 <1118624909.2128031.1566706119596@mail.yahoo.com>
 <CAB-BFRp=G1GKc8DTQ9N=haBBy1=7QHMUze5GYd6x92ZdXj59nA@mail.gmail.com>
 <1044532211.3694234.1566964607709@mail.yahoo.com>
Message-ID: <CAB-BFRqd0XXTKiiaqcFF+jJJU1Jjs8X+iJUdq1t0OT=uEAzbAQ@mail.gmail.com>

Firtst, I think that thinking about best practice advise and beeing able to
accomandate different usage scenarios is a good thing despite me arguing
against introducing the main()-idiom.

Let's have another turn on the global-environment is bad argument.

It has two parts:

(1) Glattering namespace. Glattering name space might become a problem
because you might end up having used all reasonable words already so one
has to extend the space for names with new namespaces. For scripting, this
usually should be no problem since one can always create more space through
the usage of environments - put code into a function, put objects into
environments, or write a package. Glattering name space might also become a
problem if things get complex. If your code base gets larger on name might
be overwritten by the other on accident. This is a problem that can be
solved by not simply extending the name space (more space) but by
structuring it - keeping related things together, hiding unused helpers
e.g. by putting them in a function, or an environment, or writing a
package.

Now, if we put everything into main() we have not solved much. Now instead
of 100 objects glattering the global environment we have e.g. 5 obejcts in
the global environment and 95 objects in the main()-function environment.

(2) Changing global state. A thing that is a little bit related to the
global environment is the idea of global state and the problems that arise
when changing global state. But the global environment in R is not the same
as a global state. First, all normal stuff in R (except environments, R6
objects, data.tables) are passed by copy (never mind how its implented
under the hood). So when I assign a value to a new name, this will behave
like if I made a copy - thus I simply do not care what happens to the value
of the original because my copy's value is independent. Next, it is
possible to misuse the global environment (or nay parent environment) as
global state via either explicitly using assign(..., ..., env =
globalenv()) or by using the <<- operator. Also, one has access to objects
of enclosing env?ronment when e.g. executing code in a function environment
but this is read only by default. Although this is possible and it is done
from time to time, this is not how things are done 99% of the time. The
common practice - and I would say best practice also - is to use pure
function that only depend on their inputs and do not change anything except
returing a value. Using pure functions mainly prevents 99% of the problems
with global state while using more name spaces does only chop these kind of
problems into smaller and thus more numerous problems.


Best, Peter

Am Mi., 28. Aug. 2019 um 05:56 Uhr schrieb Cyclic Group Z_1 <
cyclicgroup-z1 at yahoo.com>:

> > That beeing said I think the main task of scripts is to get things done
> via running them end to end in a fresh session. Now, it very well may
> happen that a lot of stuff has to be done. Than splitting up scripts into
> subscripts and sourcing them from a meta script is a straightforward
> solution. It might also be that some functionality is put into functions to
> be reused in other places. This can be done by putting those function
> definitions into separate files. Than one cane use source wherever those
> functions are needed. Now, putting stuff that runs code and scripts that
> define/provovide functions into the same script is a bad idea. Using the
> main()-idioms described might prevent this the problems stemming from
> mixing functions and function execution. But it would also encourage this
> mixing which is - I think, a bad idea anyways.
>
> I actually would agree entirely that files should not serve as both source
> files for re-used functions as well as application code. The suggestion for
> a main() idiom is merely to reduce variable scope and bring R practices
> more in line with generally recommended programming practices, not so that
> they can act as packages/modules/libraries. When I compared R scripts
> containing main functions to packages, I only mean in the sense that they
> help manage scope (the latter through package namespaces). Any other named
> functions besides main would be functions specifically tied to the script.
>
> I do see your point, though, that this could result in bad practice,
> namely the usage mixing you described.
>
> Best,
> CG
>

	[[alternative HTML version deleted]]



[Rd] Conventions: Use of globals and main functions
Peter Meissner