# Key Concepts

# Working Directories

As part of the grading process, student scripts are converted into HTML documents. It is easier for the instructor to review this format, if necessary, since it incorporates both the code and output in a single document. The autoharp uses the `knitr` package (Xie 2025) to achieve this goal. The process of rendering an R script (or Rmd/qmd) into an HTML file is referred to as knitting.

As part of the assignments, student scripts may need to read in local datasets, or to write to output files. Hence it is important to consider the working directory when knitting a file. The working directory is the default location that R looks when it is asked to load a file or save output. When a file is knitted, the working directory is typically the location of the file. However, this may not be ideal when grading hundreds of student scripts, across multiple assignments. The instructor would want to keep their own files separate from student output. To achieve this, the autoharp provides the functionality to specify the working directory when knitting a file, and to specify the directory where output should be written.

The only impositions that the package prescribes are:

- students should mirror the instructor set-up with respect to data and output files.
- students should use relative paths in all their scripts.

Relative paths are file paths that refer to files relative to the working directory. The alternative to relative paths are absolute paths, where a path is hard-coded. However, as pointed out in section 6.4 of “R for Data Science” (Hadley Wickham and Grolemund (2026)), the use of absolute paths hinders sharing. Thus one should only ever use relative paths in scripts.

# Environments

The autoharp relies heavily on the concept of environments within R. As described in chapter 7 (Wickham (2019)), an environment is simply a data structure that associates a set of names to a set of values. It is the key structure in how R implements lexical scoping. Every environment (except the empty environment) also contains a pointer to a parent environment. When a function is executed, it first looks within it’s execution environment for objects required. If an object cannot be found, the functions looks to the enclosing parent, and so on and so forth, until the object is found. If the object cannot be found, an error occurs.

The autoharp creates a separate environment for each student’s script. Objects created when rendering the student scripts are compared against model objects, which are created in a solution environment when the solution template is rendered.

# Forked R Processes

The `parallel` package allows a user to create forked R processes from a session. A forked session is a separate R session. It is primarily used for running parallel code. However, the autoharp uses it to sandbox the execution of student scripts.

For each student script, `render_one` creates a new fork, within which the script is rendered. The objects generated by the student code are stored in an environment within the forked process. Subsequently, test chunks are executed by the forked process within the student environment.

The above implementation ensures that objects in the global environment (where the instructor executes `render_one`) and packages loaded by the instructor do not interfere with the student code. Suppose, on the other hand, that the student scripts were executed in the same R process as the grading code. Then, if the student had forgotten to load certain packages that their code needed, but the instructor session had loaded those packages. Instead of failing to render (which is what should happen in this case), the rendering would be successful.

# `knitr` Hooks

As described in chapter 13 (Xie et al. (2020)), a chunk hook is a function that is triggered by a chunk option, when the value of this chunk option is not `NULL`. When defining a chunk hook, one can specify if the hook is to be run before or after the execution of the subsequent chunk.

The autoharp defines two hooks:

- `autoharp.objs`: The input to this hook must be a character vector. When the input is not `NULL`, the chunk hook will create a copy of each object specified in the character vector, pre-prended with a period. For instance, if the user specifies `autoharp.objs = "X"`, an object named `.X` will be created in the execution environment of the Rmd file.

  The names of model solution objects in the solution environment begin with a period.

- `autoharp.scalars`: Once again, the input to this hook must be a character vector. When not `NULL`, this character vector will be appended to a vector in the solution environment named `.scalars_to_keep`.

  This serves as a reference vector. When the test chunks are executed in the student solution environment, the objects specified in `.scalars_to_keep` will be copied out as columns in the correctness dataframe.

# References

Hadley Wickham, Mine Cetinkaya-Rundel, and Garrett Grolemund. 2026. R for Data Science (2e). O’Reilly. https://r4ds.hadley.nz/.
Wickham, Hadley. 2019. Advanced r. Chapman; hall/CRC. https://adv-r.hadley.nz.
Xie, Yihui. 2025. Knitr: A General-Purpose Package for Dynamic Report Generation in R. https://yihui.org/knitr/.
Xie, Yihui, Christophe Dervieux, and Emily Riederer. 2020. R Markdown Cookbook. Chapman; Hall/CRC. https://yihui.org/rmarkdown-cookbook/.