It's adding to the matrix of results.

Using this similar but more elegant version

```
perm <- function(v) {
n <- length(v)
if (n == 1) v
else {
X <- NULL
for (i in 1:n) X <- rbind(X, cbind(v[i], perm(v[-i])))
X
}
}
perm(letters[1:3])
#> [,1] [,2] [,3]
#> [1,] "a" "b" "c"
#> [2,] "a" "c" "b"
#> [3,] "b" "a" "c"
#> [4,] "b" "c" "a"
#> [5,] "c" "a" "b"
#> [6,] "c" "b" "a"
```

^{Created on 2020-10-18 by the reprex package (v0.3.0.9001)}

`if`

traps for a single element vector

```
for (i in 1:n) X <- rbind(X, cbind(v[i], perm(v[-i])))
```

populates a matrix by iterating over the length of the vector and taking its element at each step and creating a row in X (initially `NULL`

) with the value of that element and, the elegant part, recursively calling itself to create the columns with the remaining possibilities with the elements less that that which starts the row.