Your role has a logic problem. If v
is null, it's all right: it stops. But if v
is not null, it will continue doing the recursion indefinitely. Suppose, as in your example, that v <- c(1,2,3,5)
:
v <- c(1, 2, 3, 5)
v[-1]
[1] 2 3 5
v[-1]
is the v
vector without the first element. The second step of your recursive function is to eliminate the second element, which is equivalent to
v[-1][-1]
[1] 3 5
And that works, because R
understands that v[-1]
is a vector and therefore it is possible to remove its first position, how could it be done with v
. But see what happens if we do this a greater number of times:
v
[1] 1 2 3 5
v[-1]
[1] 2 3 5
v[-1][-1]
[1] 3 5
v[-1][-1][-1]
[1] 5
v[-1][-1][-1][-1]
numeric(0)
v[-1][-1][-1][-1][-1]
numeric(0)
v[-1][-1][-1][-1][-1][-1]
numeric(0)
Note that as soon as v
is depleted, R
continues to try to calculate its size, even if there is no size to calculate, which is what happens from v[-1][-1][-1][-1]
. This is because even though it has no element, v[-1][-1][-1][-1]
is not null:
is.null(v[-1][-1][-1][-1])
[1] FALSE
Therefore, your program does not have a stop criterion, because is.null
does not serve the desired purpose. So much so that when I run your original code on the terminal, instead of crashing like in RStudio, the error response I get is as follows:
tamanho(c(1, 2, 3, 5))
Error: C stack usage 7969280 is too close to the limit
That is, the stack pops (aka stack overflow).
You can solve this with a little change in your code:
tamanho <- function(v){
i <- 0
if (!identical(v, numeric(0))){
i <- tamanho(v[-1]) + 1
}
return(i)
}
v <- c(1, 2, 3, 5)
tamanho(v)
[1] 4
identical(v, numeric(0))
will test whether the recursion of v
arrives at numeric(0)
at some point. !
will deny this. Therefore, recursion will stop only when numeric(0)
is true.
Because the test uses numeric(0)
as a stop condition, this code is only used to calculate lengths of numeric vectors. It is up to the reader to implement a general version of it, for character, integer, logical vectors, etc.