Is it safe to use macros in R? -


i have written macros in r using defmacro function gtools package:

#' iflen macro #'  #' check whether object has non-zero length, ,  #' eval expression accordingly. #'  #' @param df object can passed \code{length} #' @param body1 if \code{length(df)} not zero, clause evaluated, otherwise, body2 evaluated. #' @param body2 see above. #' @importfrom gtools defmacro #'  #' @examples  #' iflen(c(1, 2), { print('yes!') }, {print("no!")}) #'  #' @author kaiyin #' @export iflen = gtools::defmacro(df, body1, body2 = {}, expr = {             if(length(df) != 0) {                 body1             } else {                 body2             }         })  #' iflet macro #'  #' eval expression x, assign variable, , if true, continue #' eval expression1, otherwise eval expression2. inspired clojure  #' \code{if-let} macro. #'  #' @param sym_str string converted symbol hold value of \code{x} #' @param x predicate evalueated, , assigned temporary variable described in \code{sym_str} #' @param body1 expression evaluated when temporary variable true. #' @param body2 expression evaluated when temporary variable false. #' @importfrom gtools defmacro #'  #' @examples  #' iflet("..temp..", true, {print(paste("true.", as.character(..temp..)))},  #'      {print(paste("false.", as.character(..temp..)))}) #'  #' @author kaiyin #' @export iflet = gtools::defmacro(sym_str, x, body1, body2={}, expr = {             stopifnot(is.character(sym_str))             stopifnot(length(sym_str) == 1)             assign(sym_str, x)             if(eval(as.symbol(sym_str))) {                 body1             } else {                 body2             }         })  #' ifletlen macro #'  #' similar iflet, conditioned on whether length of  #' result of \code{eval(x)} 0. #'  #'  #' @param x predicate evalueated, , assigned temporary var called \code{..temp..} #' @param body1 expression evaluated when \code{..temp..} true. #' @param body2 expression evaluated when \code{..temp..} false. #' @importfrom gtools defmacro #'  #' @examples  #' ifletlen("..temp..", 1:3, {print(paste("true.", as.character(..temp..)))},  #'      {print(paste("false.", as.character(..temp..)))}) #'  #' @author kaiyin #' @export ifletlen = gtools::defmacro(sym_str, x, body1, body2={}, expr = {             stopifnot(is.character(sym_str))             stopifnot(length(sym_str) == 1)             assign(sym_str, x)             iflen(eval(as.symbol(sym_str)), {                 body1             }, {                 body2             })         }) 

is there danger in using them?

of course have careful. macros not have own environments.

simple example f(x,y) = (x+y)^2:

m1 <- defmacro(x, y, expr = {   x <- x + y   x*x }) 

executing m1 change input variables in calling environment:

> x <- 1 > y <- 2 > m1(x, y) [1] 9 > x [1] 3 > y [1] 2 

normal r functions behave differently:

f1 <- function(x, y) {   x <- x + y   x*x }  > x <- 1 > y <- 2 > f1(x, y) [1] 9 > x [1] 1 > y [1] 2  

Comments

Popular posts from this blog

angularjs - ADAL JS Angular- WebAPI add a new role claim to the token -

php - CakePHP HttpSockets send array of paramms -

node.js - Using Node without global install -