knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) library(frite) library(purrr) library(tictoc)
frite is a package that enables us to easily write and modify functions. It can be used to inject, assign, or remove code in a function. There are also functions that enable you to use this package more easily. You can use the diagnostic functions to test any function that you can think of. It also has applications in code generation or metaprogramming.
Diagnostic
tictocify
returns a nearly identical timed version of its input is.output.same
performs call on multiple functions and sees if they match Modification
line_assign
inserts assign()
into a function line_insert
inserts code into a function line_remove
removes code from a function copy_args
copies the arguments of one function to another Helping
list_body
converts function body to a list plot_body
plots list_body()
so you can inspect the body# Defining a new function reduce_timed <- tictocify(reduce) # Now to test it against the original reduce reduce_timed(1:100000, sum, .init = 0) is.output.same(reduce_timed(1:100000, sum, .init = 0), reduce)
tictocify
will return a nearly identical timed version of a function. It does this by creating a function call and inserting tic()
, toc()
, and a return statement around the call.
is.output.same
evaluates the call in the first argument and replaces the function in the first call and re-evaluates it with a new output and checks that they are identical.
# Constructing a different version of reduce_timed (reduce_timed1 <- line_insert(reduce, after_line = 1, quote(tic()))) (reduce_timed1 <- line_assign(reduce_timed1, line = 3, 'value')) (reduce_timed1 <- line_insert(reduce_timed1, after_line = 3, quote(toc()))) (reduce_timed1 <- line_insert(reduce_timed1, after_line = 4, quote(return(value)))) is.output.same(reduce_timed(1:100000, sum, .init = 0), reduce_timed1)
Note: Everything above can be piped.
These types of modifications can be difficult to make sequentially, so there are a couple of helper functions to allow you to see what you're doing.
plot_body(map) map_hello <- map %>% line_insert(after_line = 1, quote(print("Hello!"))) list_body(map_hello) map_hello(list(1, 2, "b"), assertthat::is.number)
You can use the modification functions to build functions with recursion. A simple example is below.
spammer <- function() {} add_print <- function(.f, n) { .f <- line_insert(.f, 1, quote(print("a"))) n <- n - 1 if (n > 0) return(add_print(.f, n)) if (n == 0) return(.f) } add_print(spammer, 5)
If you want to learn more, you can view the reference manual or install frite
and begin experimenting.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.