The Art of R Programming

(WallPaper) #1
# set x and y
lxy$x <- ...
lxy$y <- ...
lxy <- f(lxy)
# use new x and y
... <- lxy$x
... <- lxy$y

As noted earlier, this code might be a bit unwieldy, especially ifxandy
are themselves lists.
By contrast, here is an alternate pattern that uses globals:

f <- function() {
...
x <<- ...
y <<- ...
}

# set x and y
x<-...
y<-...
f() # x and y are changed in here
# use new x and y
... <- x
... <- y

Arguably, this second version is much cleaner, being less cluttered and
not requiring manipulation of lists. Cleaner code is usually easier to write,
debug, and maintain.
It is for these reasons—avoiding clutter and simplifying the code—that
we chose to use globals, rather than to return lists, in the DES code earlier in
this chapter. Let’s explore that example further.
We had two global variables (both lists, encapsulating various informa-
tion):sim, associated with the library code, andmm1glbls, associated with our
M/M/1 application code. Let’s considersimfirst.
Even many programmers who have reservations about using globals
agree that such variables may be justified if they are truly global, in the
sense that they are used broadly in the program. This is the case forsim
in our DES example. It is used both in the library code (inschedevnt(),
getnextevnt(), anddosim()) and in in our M/M/1 application code (in
mm1reactevnt()). The latter access tosimis on a read-only basis in this par-
ticular instance, but it could involve writes in some applications. A common
example of such writes is when an event needs to be canceled. This might
arise in modeling a “whichever comes first” situation; two events are sched-
uled, and when one of them occurs, the other must be canceled.

172 Chapter 7

Free download pdf