rrlang

rlang::exec reacting to list


When I intentionally enter list in the exec function, the function doesn't give me an error. It gave me the value returned based on the length of the list I provided.

exec(runif, list(min = -1, max = 100))
[1] 0.01183096 0.78551700
> exec(runif, list(min = -1, max = 100, n=5))
[1] 0.11955044 0.40972682 0.04771505
> exec(runif, !!!list(min = -1, max = 100, n=5))
[1]  7.474478 65.881655 58.168154 18.761874 91.956477

What does the exec function execute?


Solution

  • exec() is the rlang version of do.call() and executes a function with the arguments provided. While do.call() takes a single list of arguments, exec() allows an arbitrary number of arguments via dynamic dots - this requires that lists of arguments be explicitly spliced by !!!. runif() will return length(n) observations if argument n is not a single numeric value.

    library(rlang)
    
    # 2 observations returned because the list is length 2.
    set.seed(0)
    exec(runif, list(min = -1, max = 100)) #
    [1] 0.8966972 0.2655087  
    set.seed(0)
    # The call being constructed and executed by `exec()`:
    runif(list(min = -1, max = 100)) # Equivalent to runif(2) 
    [1] 0.8966972 0.2655087
    
    # 3 observations returned because the list is length 3.
    set.seed(0)
    exec(runif, list(min = -1, max = 100, n=5))
    [1] 0.8966972 0.2655087 0.3721239
    set.seed(0)
    # The call being constructed and executed by `exec()`:
    runif(list(min = -1, max = 100, n=5)) # Equivalent to runif(3)
    [1] 0.8966972 0.2655087 0.3721239
    
    # Arguments are spliced and used by `runif()`
    set.seed(0)
    exec(runif, !!!list(min = -1, max = 100, n=5))
    [1] 89.77302 27.28536 37.84027 57.71248 90.91257
    set.seed(0)
    # The call being constructed and executed by `exec()`:
    runif(min = 1, max = 100, n = 5)
    [1] 89.77302 27.28536 37.84027 57.71248 90.91257