Skip to content

Latest commit

 

History

History
120 lines (81 loc) · 4.33 KB

meta-notes.md

File metadata and controls

120 lines (81 loc) · 4.33 KB

Big picture notes

r format(Sys.time(), '%d %B, %Y')

Here we record questions and comments that linger even after our group discussions.

Returning nothing and/or invisibly

Later, e.g. when reading about Environments, we had some discussion of how and why to return nothing and/or how to return invisibly. In the same way Wickham describes his own policies re: using return() and handling default values for function arguments, it would be interesting to hear his thoughts on what to return and how noisily to do so. That would be good content to add to the subsection on Return values.

Recursive functions

Also with hindsight from reading Environments, a section on recursive functions in Functions would be helpful. They are critical to solving the Environments exercises, but it's hard to learn recursive functions while also manipulating rather abstract and unfamiliar objects -- i.e. environments. All of us who worked those exercises had to practice writing much simpler recursive functions first. The explication of of where() in Recursing over environments is extremely educational; something like that would be useful in a more general introduction to recursive functions.

Multiple vs unique names

In the Environment basics section, we read that

  • "The objects don’t live in the environment so multiple names can point to the same object."
  • "Every object in an environment has a unique name."

This is confusing. In the examples and diagrams, we work with an environment e in which the object name d is bound to the vector (1, 2, 3). Then we make a new assignment e$a <- e$d and the diagram shows a and d pointing to the same vector (1, 2, 3). This suggests that the same underlying object is accessible under the names a and d, which is compatible with the first quote above. But then the second quote says that every object has a unique name. Also, we did some experimentation (see below), that makes it clear that any equivalence of a and d is very coincidental / fragile; there is definitely no long-term structural relationship between what a and d refer to.

library(pryr)
e <- new.env()
e$d <- 1:3
e$a <- e$d
e$d
## [1] 1 2 3
e$a
## [1] 1 2 3
address(e$d)
## [1] "0x103cd8aa0"
address(e$a)
## [1] "0x103cd8aa0"

At this point, reality follows the diagram. The object bound to d and that bound to a are identical and are even occupying the same memory. So it seems like there is an object that has two names! How to reconcile with "every object in an environment has a unique name"?

However, as soon as we alter an element of the vector, the link between a and d is broken.

e$d[2] <- 9
e$d
## [1] 1 9 3
e$a
## [1] 1 2 3
address(e$d)
## [1] "0x105101ad8"
address(e$a)
## [1] "0x103cd8aa0"

In terms of a statement about uniqueness in an environment, it seems like the statement should be more about names and less about objects. Is this what's meant: "in an environment, any name can be bound to at most one object," i.e. it is impossible for an environment to have two notions of a?

Names, expressions, symbols, etc.

This will probably get resolved after reading Expressions, but several exercises have exposed our ignorance of issues around names vs symbols vs expressions:

  • Exercise 3 near the end of Functions: "Write a function that opens a graphics device, runs the supplied code ...."
  • Exercise 2 in Recursing over environments: "Write your own version of get() ....".

In these contexts, we've needed to write functions where code, objects, or object names are passed as arguments of functions. There's been lots of trial and error about whether to surround code or a name with quotes, when to put multi-line expressions into curly braces, and how to use as.name(), parse(), eval().