Q:

Push return to parent function

Is there a way how to force parent function to return an output? Say I have a function that 'does something' and at the beginning of each function a want to 'check something'. If the check fails I want to return 'something else'.
In my example below 'does something' is logarithm, 'check something' means checking that the variable is nonnegative and 'something else' is minus infinity.
weird_log <- function(x) {
  check(x)
  log(x)
}

check <- function(x) {
  if (x <= 0)
    eval.parent(parse(text = 'return(-Inf)'))
}

This example doesn't work
weird_log(10)  # 2.302585
weird_log(-10) # NaN

One solution is to return 'something else' from the check function if the checks find a problem and NULL otherwise. Then I can write one if in the parent function and it's done.
weird_log <- function(x) {
  y <- check(x)
  if (!is.null(y)) return(y)
  log(x)
}

check <- function(x) {
  if (x <= 0) {
    -Inf
  } else {
    NULL
  }
}

This solution still keeps most of the functionality in separated function check() but is there a way to have all the functionality in it?

In the real problem the checking function does more than just one comparison and it is used in multiple functions so it is necessary to have it separately. Also 'something else' that returns the check function depends on condition which the input fails.

More realistic example:
weird_log <- function(input) {
  y <- check(input)
  if (!is.null(y)) return(y)
  list(log = log(input$x))
}

check <- function(input) {
  if (is.null(input$x)) {
    list(error = 'x is missing')
  } else if (!is.numeric(input$x)) {
    list(error = 'x is not numeric')
  } else if (x <= 0) {
    list(log = -Inf, warn = 'x is not positive')
  } else {
    NULL
  }
}

A:

KISS:
weird_log <- function(x) {
  if (check(x)) return(-Inf)
  log(x)
}

check <- function(x) {
  x <= 0
}

weird_log(10)  # 2.302585
weird_log(-10) # -Inf

More common is the use case where you want to throw an error when check fails:
weird_log <- function(x) {
  check(x)
  log(x)
}

check <- function(x) {
  if(x <= 0) stop("x <= 0", call. = FALSE)
}

weird_log(10)  # 2.302585
weird_log(-10) # Error: x <= 0

