At the H interactive prompt, the most convenient way to interact with
R is through quasiquotation. r
is a quasiquoter that constructs an
R expression, ships it off to R and has the expression evaluated by R,
yielding a value.
H> [r| 1 |]
0x00007f355520ab38
We do not normally manipulate R values directly, instead leaving them
alone for R to manage. In Haskell, we manipulate handles to
R values, rather than the values themselves directly. Handles have
types of the form SEXP s a
, which is actually a type synonym for
a pointer type, so values of type SEXP s a
are not terribly
interesting in their own right: they are just memory addresses, as
seen above. However, one can use H.print
to ask R to show us the
value pointed to by a handle:
H> H.printQuote [r| 1 + 1 |]
[1] 2
H> H.printQuote [r| x <- 1; x + 2 |]
[1] 3
H> H.printQuote [r| x |]
[1] 1
In the following, we will loosely identify handles to R values and R values, since the distinction between the two is seldom relevant.
The r
quasiquoter hides much of the heavy lifting of building
expressions ourselves, allowing us to conveniently use R syntax to
denote R expressions. The next sections document some advanced uses of
quasiquotes. But for now, note that r
is not the only quasiquoter
and one is free to implement new quasiquoters if
needed. One such alternative quasiquoter is rexp
, also defined in H,
which acts in much the same way as r
, except that it returns
R expressions unevaluated:
H> H.printQuote [rexp| 1 + 1 |]
expression(1+1)
Because quasiquoters ask R itself to parse expressions, at quasiquote expansion time, H itself need not implement its own R parser. This means that the entirety of R’s syntax is supported, and that it is possible to take advantage of any future additions to the R syntax for free in H, without any extra effort.
In H, graphical facilities are readily available. For example:
H> [r| plot(cars) |]
NOTE: if you resize the graphics window, you’ll notice that this
window might not be repainted. In fact, the window might not even
close properly. The reason for this is because since H is a thin
wrapper around GHCi, and
there is currently no way to mesh
GHCi’s read-eval-print loop with R’s event loop, events must be
processed manually, by calling H.refresh
at the prompt. IHaskell
does not have this limitation.