1. 재귀

재귀(Recursion)를 활용하면 코드가 매우 간결해진다. 하지만, 메모리를 많이 차지하는 단점도 있다. 재귀는 본인과 유사한 방식으로 항목을 반복 수행하는 과정(process)이다. 컴퓨터 프로그램에 대해서, 루프처럼 반복되는 명령어를 의미한다.

1.1 카운드다운

카운드다운 예제를 보면 처음 큰 숫자를 받은 함수가 있고, 이를 하나 줄인 함수가 있다. 조건이 만족되지 않아 쭉 큰 문제가 줄어들다가 마지막 1이라는 조건이 만족되면 프로그램 수행을 마치고 종료된다.

countdown <- function(i) {
  cat(i, "\n")
  if (i <= 1) {
    cat("발사(Blast off) !!!")
  } else {
    countdown(i-1)
  }
}

countdown(5)
## 5 
## 4 
## 3 
## 2 
## 1 
## 발사(Blast off) !!!

1.2 차례곱(계승, factorial)

차례곱을 while 루프를 활용하여 구할 수도 있지만, 재귀를 활용하여 코딩하게 되면 코드가 한결 간결하다. 역시, 재귀반복을 빠져나가는 기본사례 여기서는 x==1인 경우 재귀반복을 마치고 차례곱 계산을 완료한다.

fact <- function(x) {
  if (x == 1) {
    return(1)
  } else {
    return(x*fact(x-1))
  }
}

fact(5)
## [1] 120

1.3. 함수 콜스택(call stack)

재귀는 함수 콜스택과 밀접한 연관이 있다. 즉, 함수내에 함수를 실행할 경우 함수 내부의 함수가 실행을 완료할 때까지 기다린다. 따라서, 다음 greet 함수는 내부에 greet2, bye 함수가 완료되어야 실행을 완료할 수 있다.

greet2 <- function(name) {
  cat("요즘 어떻게 지내세요?", name, "님\n")
}

bye <- function() {
  cat("다음에 봐요!")
}

greet <- function(name) {
  cat("안녕하세요", name, "님\n")
  greet2(name)
  cat("작별인사를 할 준비...\n")
  bye()
}

greet("정훈")
## 안녕하세요 정훈 님
## 요즘 어떻게 지내세요? 정훈 님
## 작별인사를 할 준비...
## 다음에 봐요!