Advanced-R-Solutions icon indicating copy to clipboard operation
Advanced-R-Solutions copied to clipboard

Confusion about solution to Exercise 18.5.3 Q2

Open IndrajeetPatil opened this issue 3 years ago • 0 comments

The exact question here is the following:

Screenshot 2022-05-23 at 21 43 07

Boilerplate code from the chapter:

library(rlang)

expr_type <- function(x) {
  if (rlang::is_syntactic_literal(x)) {
    "constant"
  } else if (is.symbol(x)) {
    "symbol"
  } else if (is.call(x)) {
    "call"
  } else if (is.pairlist(x)) {
    "pairlist"
  } else {
    typeof(x)
  }
}

switch_expr <- function(x, ...) {
  switch(expr_type(x),
         ...,
         stop("Don't know how to handle type ", 
              typeof(x), call. = FALSE))
}

find_T_call <- function(x) {
  if (is_call(x, "T")) {
    x <- as.list(x)[-1]
    purrr::some(x, logical_abbr_rec)
  } else {
    purrr::some(x, logical_abbr_rec)
  }
}

logical_abbr_rec <- function(x) {
  switch_expr(
    x,
    # Base cases
    constant = FALSE,
    symbol = as_string(x) %in% c("F", "T"),
    
    # Recursive cases
    pairlist = purrr::some(x, logical_abbr_rec),
    call = find_T_call(x)
  )
}

logical_abbr <- function(x) {
  logical_abbr_rec(enexpr(x))
}

In the solution manual, you write that this is because the function can't handle closure:

Screenshot 2022-05-23 at 21 47 27

But it actually can, and it works as expected with the provided code in question:

logical_abbr(function(x = TRUE) {
  g(x + T)
})
#> [1] TRUE

It fails only when it can't find any negative case (i.e., any instance of T or F):

logical_abbr(function(x = TRUE) {
  g(x + TRUE)
})
#> Error: Don't know how to handle type integer

Am I missing something here?

IndrajeetPatil avatar May 23 '22 19:05 IndrajeetPatil