egnha / valaddin

Functional input validation to make R functions more readable and robust
Other
33 stars 1 forks source link

How does this package compare to assertthat? #1

Closed jbao closed 7 years ago

jbao commented 7 years ago

btw, thanks for the nice presentation at the meetup yesterday;-)

egnha commented 7 years ago

Thanks! Both valaddin and assertthat concern condition checking (validation), but in two different spheres, so they are not comparable: assertthat provides a collection of individual checks and a substitute for stopifnot(), whereas valaddin provides a functional operator (i.e., function transformer) that augments a function with checks. In particular, assertthat doesn't itself provide any mechanism to apply the checks to a function, giving a new "hardened" function—that's outside the scope of assertthat, you'd have to do that manually.

To illustrate the difference with an example:

f <- function(x) cat(x)

# Enhance f to apply a check to x (in fact, a check from assertthat)
f <- valaddin::strictly(f, "Not a string" ~ assertthat::is.string)

# With assertthat, to do the same you have to write a new function
f_strict_at <- function(x) {
  assertthat::assert_that(assertthat::is.string(x))
  cat(x)
}

# Alternatively, with stopifnot(), which assertthat::assert_that() replaces
f_strict_base <- function(x) {
  stopifnot(is.character(x) && length(x) == 1L)
  cat(x)
}

assertthat works with valaddin, but they are not trying to solve the same problem.

(Remark: Concerning the latter two cases, if you'd reassigned f to the function on the RHS, you'd have lost the original f-without-checks. Not a problem with valaddin, because the original function is always recoverable using valaddin::nonstrictly(). Moreover, you couldn't use f(x) in the body while (re)assigning to f, for you'd get a function with infinite recursion; again, not a problem with valaddin, because valaddin::strictly() is a functional operator.)

egnha commented 7 years ago

Updated README to clarify the distinction between checking a condition vs. transforming a function to include condition checks.