Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determining whether a function has standard evaluation

Is there any way to programmatically tell if a given function in r has standard evaluation, and if not, which component of function evaluation –

  • parsing,
  • matching,
  • scoping,
  • promise formation,
  • promise fulfillment,
  • return,

etc. – is non-standard? I understand that closures are likely to be standard, and primitives are likely to be non-standard, but there are exceptions both ways. I’m asking about determining whether the function semantics are standard with respect to each of these things, not whether the function mechanics are standard.

I assume these things ought to be derivable from a close and careful reading of the help page, and failing that the code, and failing that any referenced source code. But it would save me a great deal of grief if I had a mechanical way of quickly identifying non-standard features in the evaluation of a given function.

If there is not a way to programmatically identify all the ways in which a function is nonstandard, are there ways to test for any aspect of standardness?

like image 513
andrewH Avatar asked Sep 06 '25 07:09

andrewH


1 Answers

Quick way to check for non-standard evaluation (NSE) is to verify if certain keywords are used, e.g. substitute, eval, deparse etc. Please see the code below. It looks into the body of function and count how many times NSE-related keywords are used.

is_nse <- function(x) {
  nse_criteria <- c("substitute", "deparse", "eval", "parent.frame", "quote")
  code <- as.character(body(x))
  print(x)
  cat("-------------------------------------------------------------------\n")
  nse_count <- sapply(nse_criteria, function(x) sum(grepl(x, code)))
  if(sum(nse_count) > 0) 
    warning("Possible non-standard evaluation")
  nse_count
}

is_nse(as.Date.default)

Output:

function (x, ...) 
{
    if (inherits(x, "Date")) 
        x
    else if (is.null(x)) 
        .Date(numeric())
    else if (is.logical(x) && all(is.na(x))) 
        .Date(as.numeric(x))
    else stop(gettextf("do not know how to convert '%s' to class %s", 
        deparse1(substitute(x)), dQuote("Date")), domain = NA)
}
<bytecode: 0x0000021be90e8f18>
<environment: namespace:base>
-------------------------------------------------------------------
  substitute      deparse         eval parent.frame        quote 
           1            1            0            0            0 
Warning message:
In is_nse(as.Date.default) : Possible non-standard evaluation
like image 196
Artem Avatar answered Sep 07 '25 21:09

Artem