R/lambda.R

Defines functions defineLambda lambda makeFunction_se

Documented in defineLambda lambda makeFunction_se

#' Build an anonymous function.
#'
#' Developed from:
#' \url{http://www.win-vector.com/blog/2016/12/the-case-for-using-in-r/comment-page-1/#comment-66399},
#'  \url{https://github.com/klmr/functional#a-concise-lambda-syntax},
#'  \url{https://github.com/klmr/functional/blob/master/lambda.r}
#' Called from \code{:=} operator.
#'
#' @param params formal parameters of function, unbound names.
#' @param body substituted body of function to map arguments into (braces required for ":=" notation).
#' @param env environment to work in.
#' @return user defined function.
#'
#' @seealso \code{\link{lambda}}, \code{\link{defineLambda}}, \code{\link{named_map_builder}}
#'
#' @examples
#'
#' f <- makeFunction_se(as.name('x'), substitute({x*x}))
#' f(7)
#'
#' f <- x := { x*x }
#' f(7)
#'
#' g <- makeFunction_se(c(as.name('x'), as.name('y')), substitute({ x + 3*y }))
#' g(1,100)
#'
#' g <- c(x,y) := { x + 3*y }
#' g(1,100)
#'
#' @export
#'
makeFunction_se <- function(params, body, env = parent.frame()) {
  force(env)
  vars <- as.character(params)
  formals <- replicate(length(vars), quote(expr = ))
  names(formals) <- vars
  eval(call('function', as.pairlist(formals), body),
       envir = env,
       enclos = env)
}



#' Build an anonymous function.
#'
#' Mostly just a place-holder so lambda-symbol form has somewhere safe to hang its help entry.
#'
#' @param ... formal parameters of function, unbound names, followed by function body (code/language).
#' @param env environment to work in
#' @return user defined function.
#'
#'
#' @seealso \code{\link{defineLambda}}, \code{\link{makeFunction_se}}, \code{\link{named_map_builder}}
#'
#' @examples
#'
#' #lambda-syntax: lambda(arg [, arg]*, body [, env=env])
#' # also works with lambda character as function name
#' # print(intToUtf8(0x03BB))
#'
#' # example: square numbers
#' sapply(1:4, lambda(x, x^2))
#'
#' # example more than one argument
#' f <- lambda(x, y, x+y)
#' f(2,4)
#'
#' # brace interface syntax
#' f <- x := { x^2 }
#' f(5)
#'
#' # formula interface syntax: [~arg|arg(~arg)+] := { body }
#' f <- x~y := { x + 3 * y }
#' f(5, 47)
#'
#' @export
#'
lambda <- function(..., env = parent.frame()) {
  force(env)
  args <- base::substitute(list(...))
  body <- args[[length(args)]]
  args <- args[-length(args)]
  params <- base::lapply(args[-1], base::as.name)
  wrapr::makeFunction_se(params, body, env)
}



#' Define lambda function building function.
#'
#' Use this to place a copy of the lambda-symbol
#' function builder in your workspace.
#'
#' @param envir environment to work in.
#' @param name character, name to assign to (defaults to Greek lambda).
#'
#' @seealso \code{\link{lambda}}, \code{\link{makeFunction_se}}, \code{\link{named_map_builder}}
#'
#' @examples
#'
#' defineLambda()
#' # ls()
#'
#' @export
#'
defineLambda <- function(envir = parent.frame(), name = NULL) {
  force(envir)
  if(is.null(name)) {
    name <- intToUtf8(0x03BB)
  }
  assign(name, wrapr::lambda, envir = envir)
}
WinVector/wrapr documentation built on Oct. 17, 2018, 8:20 p.m.