Function operators (FOs) seem like a great way to increase productivity and make the best of R's functional programming chops, perhaps especially in package development.
Keeps functions nice and small, without having to built a gazillion wrappers and passing around arguments like a crazy person.
the solutions to Hadley Wickham’s book "Advanced R" contributed by Malte Grosser, Henning Bumann, Peter Hurford and Robert Krzyzanowski (see chapters: Behavioural FOs, Output FOs, Input FOs, Combining FOs)
I skimmed all the functions from base and utils looking for function operators and I only found base::Negate() and base::Vectorize() though I might have missed some.
utils::getS3method() is "almost" a function operator as it takes a function name as a string and returns a function.
Another function that modifies a function (its behavior at least) is trace() but it doesn't return a function.
base::body<- and base::formals<- can also be used to modify a function, but they don't return a function either.
I'm not sure if this is what you had in mind in terms of increasing productivity in general programming, but the color palette and interpolation functions are some additional examples of functions that return functions. For example:
thanks @joels, I was indeed more looking for function operators; I was simply wondering whether there might be a list of really cool FOs somewhere, or what FOs people are using.
Actually body<- and formals<- are legit function operators, I wasn't thinking straight. In their standard form body(f) <- rhs the expression returns the rhs, but that's not relevant.
I found about crayon which has the clever the function operator crayon:::`$.crayon` to grow the _styles attribute of it's input.
@maxheld83 maybe you'll be interested in this, I updated my package and it's full of new function operators and an API to easily build them or use them. If you are I'll be happy to read your thoughts.
@maxheld83 these packages are now ready to be used, there's more than 50 tags (function operator factories). I made adverb factories from all the purrr and base adverbs, all the with_* functions from withr, progress::progress_bar and much more. See README intro below :
This package consists of a collection of tags built using the functions and
principle designed and described in the package tag. See the read me at : https://github.com/moodymudskipper/tag.
It allows things like the following :
library(tags)
df_name <- "iris"
# use quasi quotation with any function
using_bang$head(!!rlang::sym(df_name),1)
# use purrr adverbs with tag syntax
using_possibly$log("a", .otherwise = NA_real_)
# use withr functions with tag syntax
setting_options(list(scipen = 100))$print(exp(100))
The package contains over 50 tags that can be divided into the
following categories.
tag counterparts to base and purrr adverbs :
vectorizing (wraps base::Vectorize)
negating (wraps base::Negate)
using_safely (borrows code from purrr::safely)
using_quietly (borrows code from purrr::quietly)
using_possibly (borrows code from purrr::possibly)
tag counterparts to withr functions :
all 31 withr::with_* functions have tags::setting_* counterparts
tag expanding tidyverse features :
using_bang to make any function compatible with quasi-quotation
using_lambda to use formula notation in any functional
grouping_by to use dplyr::group_by on a single operation
using_rowwise to use dplyr::rowwise on a single operation
selecting_dots, renaming_dots, mutating_dots, transmuting_dots, reversing_dots to edit the dots passed to a call before it's executed,
using dplyr semantics.
tags focused on side effects
logging to print call and execution time (wraps Sys.time())
suppressing_warnings to selectively suppress warnings based on a regular
expression.
viewing (wraps utils::View)
debugging (wraps base::debugonce)
progressing to add a progress bar to any functional (wraps progress::progress_bar)
beeping to play a sound once the call is over (wraps beepr::beep)
popping_up to trigger a message box once the call is over (wraps tcltk::tk_messageBox)
other tags
composing as an alternative to piping/functional sequences (wraps magrittr's functional sequences)
using as the tag counterpart to with, with extra features
mapping to loop over argument values (wraps foreach::foreach)
self_referencing to avoid variable repetition with functions such as base::transform / dplyr::mutate, dplyr::summarize
tracing as a tag counterpart to base::trace
enclosing to enclose the input function in another function.
preserving_attr to make sure some attributes are preserved
checking_args to operate checks on arguments before calling the function