14.1 Programming Paradigms

Let us begin by exploring the notion of a programming paradigm in general. We will go on in this Chapter to consider two programming paradigms for which R provides considerable support. In the next Chapter we will consider a third programming paradigm that exists in R.

A programming paradigm is a way to describe some of the features of programming languages. Often a paradigm includes principles concerning the use of these features, or embodies a view that these features have special importance and utility in good programming practice.

14.1.1 Procedural Programming

One of the older programming paradigms in existence is procedural programming. It is supported in many popular languages and is often the first paradigm within which beginners learn to program. In fact, if one’s programming does not progress beyond a rudimentary level, one may never become aware that one is working within the procedural paradigm—or any paradigm at all, for that matter.

Before we define procedural programming, let’s illustrate it with an example. Almost any of the programs we have written so far would do as examples; for specificity, let’s consider the following snippet of code that produces from the data frame m111survey a new, smaller frame consisting of just the numerical variables:

library(bcscr)
# find the numer of columns in the data frame:
cols <- length(names(m111survey))
#set up a logical vector of length equal to the number of columns:
isNumerical <- logical(cols)

# loop through.  For each variable, say if it is numerical:
for ( i in seq_along(isNumerical) ) {
  isNumerical[i] <- if (is.numeric(m111survey[, i])) TRUE else FALSE
}

# pick the numerical variables from the data frame
numsm111 <- m111survey[, isNumerical]
# have a look at the result:
str(numsm111)
## 'data.frame':    71 obs. of  6 variables:
##  $ height         : num  76 74 64 62 72 70.8 70 79 59 67 ...
##  $ ideal_ht       : num  78 76 NA 65 72 NA 72 76 61 67 ...
##  $ sleep          : num  9.5 7 9 7 8 10 4 6 7 7 ...
##  $ fastest        : int  119 110 85 100 95 100 85 160 90 90 ...
##  $ GPA            : num  3.56 2.5 3.8 3.5 3.2 3.1 3.68 2.7 2.8 NA ...
##  $ diff.ideal.act.: num  2 2 NA 3 0 NA 2 -3 2 0 ...

By now there is nothing mysterious about the above code-snippet. What we want to become conscious of is the approach we have taken to the problem of selecting the numerical variables. In particular, observe that:

  • We worked throughout with data, some of which, like m111survey, was given to us and some of which we created on our own to help solve the problem. For example, we created the variable cols. Note also the very helpful index-variable i in the for-loop. We set up the data structure isNumerical in order to hold a set of data (TRUEs and FALSEs).
  • We relied on various procedures to create data and to manipulate that data in order to produce the desired result. Some of the procedures appeared as special blocks of code—most notably the for-loop, but also the if-else construct within the loop. Other procedures took the form of functions. As we know, a function encapsulates a useful procedure so that it can be easily reused in a wide variety of circumstances, without the user having to know the details of how it works. We know that names() will give us the vector of names of the columns of m111survey, that length() will tell us how many names, there are, that is.numeric() will tell us whether or not a given variable in m111survey is a numerical variable, and so on. The procedures embodied in these functions were written by other folks and we could examine them if we had the time and interest, but for the most part we are content simply to know how to access them.

Procedural programming is a paradigm that solves problems with programs that can be broken up into collections of variables, data structures and procedures. In this paradigm, there is a sharp distinction between variables and data structures on the one hand and procedures on the other. Variables and data structures are data—they are the “stuff” that a program manipulates to produce other data, other “stuff.” Procedures do the manipulating, turning stuff into other stuff.