r - Is it safe to replace && and || by purely scalar operators in my package? -


as follow-up my previous question on usage of && , || in if statements, wondering whether there drawback replacing && , || purely scalar operators in own package. these should produce same results base counterparts, except throw error messages when applied arguments of length > 1. in particular, short-circuiting.

`&&` <- function(x, y) {     if (!x[1]) {         stopifnot(length(x) == 1)         return(false)     }     stopifnot(length(x) == 1)     if (!y[1]) {         stopifnot(length(y) == 1)         return(false)     }     stopifnot(length(y) == 1)     true }  `||` <- function(x, y) {     if (x[1]) {         stopifnot(length(x) == 1)         return(true)     }     stopifnot(length(x) == 1)     if (y[1]) {         stopifnot(length(y) == 1)         return(true)     }     stopifnot(length(y) == 1)     false } 

is safe these replacements in package? or might break something? (except functions rely on vectorised behavior, obviously...)

note not plan export these functions; internal use in package.

if understand correctly, these replacements should affect own functions. can't affect outside of package, right?

no. might able make safe computer, code needs safe reader too. someday you'll want share code others, or you'll come after time away, , kind of overloading confusing. better far use new function name.

also, you'll need very careful how functions handle na , null values. current version has different behaviors usual ones na, , possibly null; didn't full check. surprised notice, though, when 1 of inputs null, order matters standard r versions.

edit: issue na values think hard about, , possibly reason not write single function intended replace && , ||. flow control, need either true or false, na throw error. should true && na throw error? or false? or true? may depend, , doing usual thing of if(!is.na(x) && x) or if(any(is.na(x))) may offer more flexibility , clarity reader.

if proceed, preference think of new versions scalar versions of all , any , name them accordingly, used scalar.all(a, b) instead of a && b. or perhaps if you're thinking flow control perspective, add parameter describe na values, flowcontrol.all(a, b, na=c("error", "true", "false").

by way, applaud efforts, in general. being aware of these issues , writing code safe them seems idea. however, after thinking more , trying briefly write own versions, feel within own package preferable needed on case case basis. there times when you'll know package writer 1 or both of inputs can scalar, , code unnecessary.

still, here's attempt @ scalar.all function.

scalar.all <- function(...) {    ns <- eval(substitute(alist(...)))    sofar <- true    for(n in ns) {       x <- eval(n)       if (length(x) != 1l) {         stop(paste(list(n)), " not scalar length 1")       }       if (is.na(x)) sofar <- na       else if (!x) return(false)    }    sofar } 

Comments