Is there a function to know when a function was released?

Viewed 80

When developing a package, it's useful to know when a function that we want to use was introduced in R or in a dependency, so that we know whether including it will change the dependencies of our package. Is there a function that takes a function name as input and outputs the R version or the package version in which it was released?

Example:

implemented_in("list2DF()")
#> '4.0.0'

Even better if this function could work for every package and not just for base R, for example:

implemented_in("dplyr::relocate()")
#> '1.0.0'
3 Answers

I made a small package for this. It doesn't extract the version in which a function was introduced but it gets all mentions of a function in the NEWS. Therefore, you can find when a function was added, but also when it was modified:

library(getnews)

getnews("paste0")
#> VERSION 2.15.0 
#>  =========== 
#> 
#>  New function paste0(), an efficient version of paste(*,
#> sep=""), to be used in many places for more concise (and
#> slightly more efficient) code. 
#> 
#> 
#> VERSION 4.0.1 
#>  =========== 
#> 
#>  paste() and paste0() gain a new optional argument recycle0.
#> When set to true, zero-length arguments are recycled leading to
#> character(0) after the sep-concatenation, i.e., to the empty
#> string "" if collapse is a string and to the zero-length value
#> character(0) when collapse = NULL.
#> 
#> A package whose code uses this should depend on R (>= 4.0.1).

getnews("adist")
#> VERSION 2.14.0 
#>  =========== 
#> 
#>  New function adist() in package utils for computing ‘edit’
#> (generalized Levenshtein) distances between strings.

getnews("relocate", "dplyr")
#> VERSION 1.0.0 
#>  =========== 
#>  New relocate() verb makes it easy to move columns around within a
#>     data frame (#4598).
#> 
#>   
#> 
#> VERSION 1.0.3 
#>  =========== 
#>  relocate() can rename columns it relocates (#5569).
#> 
#> 

Created on 2022-07-09 by the reprex package (v2.0.1)

Link to the package

You could search through the NAMESPACE files of package versions to find the first time a function has been exported. Two packages help with this: pkgsearch can be used to find all CRAN versions of a contributed package, and pacs can retrieve and read NAMESPACE files.

A simple version (without handling any edge cases) of such a search function could look like this:

implemented_in <- function(fn, pkg) {
  history <- pkgsearch::cran_package_history(pkg)
  
  # Always search at least one version
  last_without <- 0
  first_with <- nrow(history) + 1
  
  # Binary search to avoid reading all NAMESPACE files
  while (first_with - last_without > 1) {
    next_index <- floor((last_without + first_with) / 2)
    
    version <- history[next_index, ]$Version
    ns <- pacs::pac_namespace(pkg, version = version)
    
    if (fn %in% ns$exports) {
      first_with <- next_index
    } else {
      last_without <- next_index
    }
  }
  
  history[first_with, ]$Version
}

implemented_in("relocate", "dplyr")
#> [1] "1.0.0"

However, this approach doesn't work for base R functions.

Actually, there's a package for that: apicheck. It's slower than printing the news, but probably more robust and tested (and it has much more functionalities as well):

library(apicheck) # hughjonesd/apicheck

when_fun_exists("base::list2DF", report = "brief")
#> [1] "4.0.0"

Created on 2022-07-26 by the reprex package (v2.0.1)

Related