Search code examples
rprogramming-languagesevaluationreduction

Does R use applicative order reduction?


I came across this example from an R tutorial recently and I found this syntax really odd because it hints towards normal order reduction where arguments are wrapped / delayed. In applicative order reduction something like this should result in all the strings printing.

switch(grade,
       "A" = print("Great"),
       "B" = print("Good"),
       "C" = print("Ok"),
       "D" = print("Bad"),
       "F" = print("Terrible"),
       print("No Such Grade"))

Was wondering if anyone is privy and familiar with how R implements this?


Solution

  • Arguments to functions, including switch, are passed as promises which are forced, i.e. evaluated, only when actually used. See https://cran.r-project.org/doc/manuals/R-ints.html#Argument-evaluation

    A promise has several parts. Its value slot is filled in the first time it is forced (i.e. accessed). Until then it just exists as unevaluated code and its environment as well as components which indicate that it has not been evaluated.

    f does not force x:

    library(pryr)
    f <- function(x) promise_info(x)
    f(3+pi)
    

    giving:

    $code
    3 + pi
    
    $env
    <environment: R_GlobalEnv>
    
    $evaled
    [1] FALSE
    
    $value
    NULL
    

    g forces x:

    g <- function(x) { force(x); promise_info(x) }
    g(3 + pi)
    

    giving:

    $code
    3 + pi
    
    $env
    NULL
    
    $evaled
    [1] TRUE
    
    $value
    [1] 6.141593