简体   繁体   English

为什么在递归 R 函数中“+”失败时“Sum()”会成功?

[英]Why does “Sum()” succeed where “+” fails in recursive R function?

I am experimenting with the functional programming paradigm in R. I have defined a function that sums a sequence of integers from n to m .我正在试验 R 中的函数式编程范式。我定义了一个函数,它对从nm的整数序列求和。 When I use sum() the function returns the expected result:当我使用sum()该函数返回预期结果:

sumRange <- function(n, m) {
    if (n <= m) { 
        return(sum(n, sumRange((n + 1), m)))
    }
}

sumRange(1, 10)
# [1] 55

However, when I use the + operator the function returns numeric(0) :但是,当我使用+运算符时,该函数返回numeric(0)

sumRange <- function(n, m) {
    if (n <= m) {
        return(n + sumRange((n + 1), m))
    }
}

sumRange(1, 10)
# numeric(0)

Why does the operator + not work in this recursive function?为什么运算符+在这个递归函数中不起作用? Is there a way to rewrite the function so that it does?有没有办法重写这个函数,让它这样做?

The issue is that you never specify an else condition, hence at the end of the recursion it appears that R is returning NULL when the if condition fails.问题是您从未指定 else 条件,因此在递归结束时, if条件失败时,R 似乎返回NULL Returning 0 as the else condition fixes your problem:返回 0 作为 else 条件可以解决您的问题:

sumRange <- function(n, m) return(ifelse (n <= m, (n +  sumRange((n+1), m)), 0))
sumRange(1, 10)
[1] 55

Note that this is essentially defining a base case for your recursion.请注意,这实际上是为您的递归定义一个基本情况 A base case, when hit, ends the recursion and causes the calls on the stack to be unwound.一个基本情况,当命中时,结束递归并导致堆栈上的调用被展开。

To see the issue with the way you phrased your code, try writing out your function explicitly:要查看您编写代码的方式的问题,请尝试明确地写出您的函数:

sumRange <- function(n, m) {
    if (n <= m) {
        return(n + sumRange((n+1), m))
    }
    // but what gets returned if n > m ?
    // this is undefined behavior
}

I'm not an R guru, but my understanding is that R was written in C, and C might allow a recursion like this with no else condition.我不是 R 大师,但我的理解是 R 是用 C 编写的,C 可能允许这样的递归,没有else条件。 But the behavior is not well defined and you should not be relying on it.但是行为没有明确定义,你不应该依赖它。

Demo演示

If there is no return (using a explicit or implicit return statement) is executed, then R functions seems to return a NULL object.如果没有执行 return(使用显式或隐式 return 语句),则 R 函数似乎返回一个NULL对象。

If you add numerical value to a this object, it will simply return numeric(0) .如果将数值添加到 this 对象,它将简单地返回numeric(0)

So, what happens in the second case is that when n reaches 11, it returns a NULL object, and goes back adding values to it.因此,在第二种情况下发生的情况是,当n达到 11 时,它返回一个NULL对象,并返回向其添加值。 But NULL + 10 + 9 .. = numeric(0) .但是NULL + 10 + 9 .. = numeric(0)

Check this with检查这个

no_ret <- function ()
{
 # just return nothing
}

obj <- no_ret()
obj
# NULL 
class(obj)
# "NULL
new_obj <- obj + 10
new_obj
# numeric(0)

When the first function is executed, the what the sum statement get is a vector with a NULL in it.当第一个函数被执行时,sum 语句得到的是一个带有NULL的向量。 For example, vec <- c(NULL, 10, 9,...) which is actually vec <- c(10, 9, ...) , so you get the expected outcome.例如, vec <- c(NULL, 10, 9,...)实际上是vec <- c(10, 9, ...) ,所以你得到了预期的结果。

> c(NULL, 10:1)
 [1] 10  9  8  7  6  5  4  3  2  1
> sum(NULL, 10:1)
[1] 55

> NULL + 10:1
integer(0)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM