%\VignetteDepends{}
%\VignetteIndexEntry{Native Interfaces Exercises}
%\VignettePackage{AdvancedR}

\documentclass{article}

\usepackage[colorlinks=true,linkcolor=blue]{hyperref}
\usepackage{theorem}
\usepackage{underscore}
\usepackage{color}

\newcommand{\Rfunction}[1]{{\texttt{#1}}}
\newcommand{\Rmethod}[1]{{\texttt{#1}}}
\newcommand{\Robject}[1]{{\texttt{#1}}}
\newcommand{\Rpackage}[1]{{\textsf{#1}}}
\newcommand{\Rfunarg}[1]{{\texttt{#1}}}
\newcommand{\Rclass}[1]{{\textit{#1}}}

\newcommand{\code}[1]{{\texttt{#1}}}
\newcommand{\file}[1]{{\texttt{#1}}}

\newcommand{\software}[1]{\textsf{#1}}
\newcommand{\R}{\software{R}}
\newcommand{\bioc}{\software{BioConductor}}
\newcommand{\ELAND}{\software{ELAND}}
\newcommand{\MAQ}{\software{MAQ}}
\newcommand{\Bowtie}{\software{Bowtie}}

%% Excercises and Questions
\theoremstyle{break} \newtheorem{Ex}{Exercise}
\theoremstyle{break} \newtheorem{Q}{Question}
%% And solution or answer
\newenvironment{solution}{\color{blue}}{\bigskip}

\begin{document}

\SweaveOpts{keep.source=TRUE,width=9,height=8,eps=FALSE,include=FALSE,prefix.string=niFig}

\title{Native Interfaces for R: Self-Study Exercises}
\author{Seth Falcon}
\date{20-21 May, 2010}
\maketitle

%% \tableofcontents

<<setup, echo=FALSE>>=
options(width=60)
@

\section{Exercises}

The \Rpackage{AdvancedR} package contains the sources of the
\Rpackage{nidemo} package that demonstrates how to use R's native
interfaces.  The exercises below will take the \Rpackage{nidemo}
package code as a starting point, so you will want to have the source
for this package at hand.  If you have installed the
\Rpackage{AdvancedR} package, you can find the sources for
\Rpackage{nidemo} as follows:

<<findingnidemo>>=
system.file("packages", package = "AdvancedR")
@

The \Rpackage{nidemo} package contains two versions of a function that
computes the occurrence counts of the letters a--z in a text
file.  The \Rfunction{alpha\_freq\_R} function is written entirely in
R and the \Rfunction{alpha\_freq} function performs the letter
counting in a C function accessed via \Rfunction{.Call}.

\begin{Ex}
  Install the \Rpackage{nidemo} package and test out both
  \Rfunction{alpha\_freq\_R} and \Rfunction{alpha\_freq}.  On
  unix-like systems, a good input file to use for testing is the
  system word dictionary (possibly in \code{/usr/share/dict/words}).

  Use \Rfunction{system.time} to compare the run time for the two
  versions.  You may not see much of a difference if your input file
  is small.
\end{Ex}

  The C function \Rfunction{nid\_alpha\_freq} in
  \code{nidemo/src/charfreq.c} is not very robust.  In particular, the
  function does not verify that the argument it receives is of the
  type that it expects.  When a bad argument is provides, it will
  crash R.

\begin{Ex} \label{exBadInput}
  Try the following inputs to see the ways in which the function
  breaks (NOTE: some or all of these may crash your R session).

  \begin{itemize}
  \item \code{alpha\_freq(TRUE)}
  \item \code{alpha\_freq("")}
  \item \code{alpha\_freq(as.character(NA))}
      \item \code{alpha\_freq(character(0))}
  \end{itemize}
\end{Ex}

\begin{Ex}
  Modify the \Rfunction{nid\_alpha\_freq} function to display a
  standard R error message when the argument provided is invalid.  Do
  this in C, not in the R wrapper function using \code{Rf\_error}.
  After your changes, the function should provide an error message for
  all of the invalid inputs from Exercise~\ref{exBadInput}.  Hint: you
  can use \code{Rf_isString} to test for a character vector.
\end{Ex}

\begin{Ex}
  Force the input to be \code{character(1)} by making it an error if
  the input is not of the right length.  Do this in C.
\end{Ex}

\begin{Ex}
  Use \Rfunction{TYPEOF()} and \Rfunction{Rf_type2char()} to provide a
  more informative error message when the input is not a character
  vector.
\end{Ex}

\begin{Ex}
  The labels for the result table are set in the R wrapper for
  \Rfunction{alpha\_freq}.  Modify the code to set the names of the
  result table in C.  Outline:
  \begin{itemize}
  \item Create a character vector using
    \code{Rf\_allocVector(STRSXP, 26)}
  \item Use \code{SET\_STRING\_ELT} and \code{mkChar} to fill the
    vector
  \item Set this as the names attribute of the return SEXP using
    \code{Rf\_setAttrib}.  The attribute name is
    \code{R\_NamesSymbol}.
  \end{itemize}
\end{Ex}


\begin{Ex}
  At the top of \Rfunction{nid\_alpha\_freq}, an INTSXP is allocated
  using \Rfunction{Rf\_allocVector}.  This vector is protected a few
  lines later.  Is this safe?  Discuss.
\end{Ex}

\begin{Ex}
  Enhance \Rfunction{alpha\_freq} so that it can be given a length $n$
  vector of file names and return an $n \times 26$ matrix with the
  alphabet frequency count for each file.  Set the row names of the
  matrix to be the corresponding file names.  There is an example of
  returning a matrix from a C function in WRE.
\end{Ex}

\section{R Package Development Setup}

\subsection{Makevars customization}

You can ensure that debugging symbols and compiler warnings are
enabled for all packages that you build from source by creating a
\code{Makevars-PLATFORM} file in your home directory (where PLATFORM
matches the output of \verb+R.version$platform+.

<<makevars, eval=FALSE>>=
dir.create("~/.R", showWarnings = FALSE)
lines <- "CFLAGS=-g -Wall -pedantic"
fname <- paste("~/.R/Makevars",
               R.version[["platform"]],
               sep = "-")
writeLines(lines, con = fname)
@

\subsection{Useful items for \code{\$HOME/.Rprofile}}

\begin{itemize}

\item Install packages based on the \verb+R_LIBS_USER+ environment
  variable.  This keeps installed packages separate from the packages
  that come with R and also has the advantage of avoiding mixing
  packages across different versions of R.

\item Set a default CRAN repository

\item Source \code{biocLite} script for interactive sessions.

\item A helper function to reload a package, useful during
  development.

\end{itemize}

\begin{verbatim}
dir.create(Sys.getenv("R_LIBS_USER"),
           recursive = TRUE,
           showWarnings = FALSE)

options(repos="http://cran.fhcrc.org")

if (TRUE && interactive()) {
tryCatch({
    source("http://bioconductor.org/biocLite.R")
}, error=function(e) invisible(NULL),
         warning=function(w) message("Not connected to the net"))
}

reload_pkg <- function(p)
{
    detach(paste("package", p, sep = ":"),
           unload = TRUE, character.only = TRUE)
    library(p, character.only = TRUE)
}

\end{verbatim}

\subsection{Windows Setup}

For reference, read the \textit{Installing R under Windows} in the
\textit{R Installation and Administration} manual.

Download and install the standard R package for Windows.

Download the appropriate version of the Windows tools from
\url{http://www.murdoch-sutherland.com/Rtools/} and install.

Install a package from source as:

\begin{verbatim}
c:\"Program Files\R\R-2.11.0"\bin\R CMD INSTALL nidemo
\end{verbatim}

\section{Exploration of External Pointers}

R provides the EXTPTRSXP type for managing memory that is external to
R.  You can register a \textit{finalizer} that will run when an
external pointers is garbage collected.  See Figure~\ref{figExtPtr}.

\begin{figure}[hb]
  \includegraphics[width=2in]{nativeI/extptrsxp-diagram}
  \caption{Conceptual diagram of R's external pointer type (EXTPTRSXP)}
  \label{figExtPtr}
\end{figure}

The \Rpackage{nidemo} package contains an example of using R's
external pointers.  The code is somewhat contrived, but extends the
alphabet frequency counter to be a persistent data structure such that
you can create a counter and update it with the contents of different
files and then retrieve the cumulative alphabet frequency counts.

A user session looks like this:

<<alphafreqextptrsession, eval=FALSE>>=
x <- make_freq("alice")
update_freq(x, "some/file.txt")
update_freq(x, "some/another.txt")
report_freq(x)
rm(x)
gc()
@

\begin{Ex}
  Read through the implementation of the external pointer based
  alphabet frequency counter and try out a sample session.
\end{Ex}

In addition to registering finalizers at the C-level, it is also
possible to create R-based finalizers using \Rfunction{reg.finalizer}.
One subtlety of finalizers is that any functions called within a
finalizer must satisfy a weak-form of re-entrancy.  Consider the
pseudo-code in Figure~\ref{figReent}.

\begin{figure}
\begin{minipage}{0.8\textwidth}
\begin{verbatim}
f() {
  /* amazing computations */
  g() /* this allocates R objects,
         can trigger gc */
  /* more computations here */
}

finalizer() {
  /* clean up */
  f() /* danger! */
}
\end{verbatim}
\end{minipage}
\caption{Even though R is single-threaded, a second call to \code{f}
  will occur before the first call to \code{f} is finished.  This can
  cause serious problems if \code{f} manipulates global variables or
  modifies its arguments in-place.}
\label{figReent}
\end{figure}

\section{Calling R from C}

You can evaluate R code from C using \code{Rf\_eval}.  This allows
package code to make use of R functions that do not have a C entry
point as well as provide a mechanism for users to specify callback
functions in R that will be executed in the context of package C code.

\begin{Ex}
  Take a few minutes to review the section
  \textit{Evaluating R expressions from C} in the WRE manual.
\end{Ex}

The most elegant way of calling R functions from C is to build a
function call using a LANGSXP and then evaluate it using
\code{Rf\_eval}.  R function calls are represented in C using the
LANGSXP type that provides a linked list data structure.  The first
element of the list must be a symbol naming the function you want to
call (SYMSXP).  Additional elements in the list are the arguments to
the function.

There are helper functions to construct pairlists of different sizes:
\code{lang1}, \code{lang2}, \code{lang3}, \code{lang4}.  Below,
\code{Rf\_lang2} is used to call \Rfunction{path.expand} at the C
level.

\begin{verbatim}
PROTECT(v = Rf_mkString("~/src/somefile.txt"));
PROTECT(fun = Rf_lang2(Rf_install("path.expand"), v));
ans = eval(fun, R_BaseEnv);
\end{verbatim}

\begin{Ex}
  Enhance the \code{nid\_alpha\_freq} function in
  \code{nidemo/src/charfreq.c} so that file names are expanded.  Do
  this by constructing a call to \Rfunction{path.expand} at the C
  level.
\end{Ex}

\end{document}
