R 함수 인자 평가

R 함수 인자 평가 (Argument evaluation)

이 섹션에서는 R에서 함수 인자가 어떻게 평가되는지, 특히 제공된 인자와 기본 인자의 차이를 중심으로 알아볼게요. 평가 프레임과 지연 평가의 개념도 함께 살펴보면서, R의 독특한 인자 처리 방식을 이해해 보도록 해요.

출처: R Language Definition

본문

4.3.3 인자 평가

함수 인자의 평가에 대해 가장 중요하게 알아야 할 점 중 하나는, 제공된 인자(supplied arguments)와 기본 인자(default arguments)가 서로 다르게 처리된다는 거예요. 함수에 제공된 인자는 호출 함수(calling function)의 평가 프레임에서 평가돼요. 함수의 기본 인자는 해당 함수 자신의 평가 프레임에서 평가되고요.

R에서 함수 호출의 의미는 call-by-value (값에 의한 호출)이에요. 일반적으로 제공된 인자는 해당 형식 인자(formal argument)의 이름으로, 제공된 값으로 초기화된 지역 변수처럼 동작해요. 함수 안에서 제공된 인자의 값을 바꿔도 호출 프레임에 있는 변수의 값에는 영향을 주지 않아요.

R에는 함수 인자에 대한 지연 평가(lazy evaluation) 형태가 있어요. 인자는 필요할 때까지 평가되지 않아요. 경우에 따라 인자가 절대 평가되지 않을 수도 있다는 점을 알아두는 게 중요해요. 따라서 함수 인자를 이용해 부작용(side-effect)을 일으키는 방식은 좋은 스타일이 아니에요. C에서는 foo(x = y) 같은 형태로 y의 값을 foo에 넘기면서 동시에 y 값을 x에 할당하는 것이 흔하지만, R에서는 같은 방식을 사용하면 안 돼요. 인자가 실제로 평가된다는 보장이 없으므로 할당이 일어나지 않을 수도 있어요.

또한 foo(x <- y)의 경우, 인자가 평가된다면 x의 값이 foo의 평가 환경이 아니라 호출 환경(calling environment)에서 바뀐다는 점도 기억해 둘 만해요.

함수 내부에서 인자로 사용된 실제(기본이 아닌) 표현식에 접근하는 것도 가능해요. 이 메커니즘은 프로미스(promise)를 통해 구현돼요. 함수가 평가되는 동안 인자로 사용된 실제 표현식은 프로미스에 저장되는데, 함수가 호출된 환경을 가리키는 포인터도 함께 저장돼요. 인자가 평가될 때(만약 평가된다면) 저장된 표현식은 함수가 호출된 환경에서 평가돼요. 환경에 대한 포인터만 사용되기 때문에, 그 환경에서 일어난 변경 사항은 이 평가 중에 적용돼요. 그 결과 값은 프로미스 안의 별도 공간에 저장되고, 이후 평가에서는 이 저장된 값을 가져와요 (두 번째 평가는 일어나지 않아요). 또한 substitute를 사용하면 평가되지 않은 표현식에도 접근할 수 있어요.

함수가 호출되면, 각 형식 인자는 호출의 지역 환경에 프로미스를 할당받아요. 이때 표현식 슬롯에는 실제 인자(존재한다면)가 들어 있고, 환경 슬롯에는 호출자의 환경이 들어 있어요. 호출에서 형식 인자에 대한 실제 인자가 주어지지 않고 기본 표현식이 있다면, 그 표현식도 마찬가지로 형식 인자의 표현식 슬롯에 할당되지만, 환경은 지역 환경으로 설정돼요.

프로미스의 환경에서 표현식 슬롯의 내용을 평가하여 값 슬롯을 채우는 과정을 프로미스를 *강제 평가(forcing)*한다고 해요. 프로미스는 한 번만 강제 평가되며, 이후에는 값 슬롯의 내용이 직접 사용돼요.

프로미스는 그 값이 필요할 때 강제 평가돼요. 보통 내부 함수 안에서 일어나지만, 프로미스 자체를 직접 평가해서 강제 평가할 수도 있어요. 기본 표현식이 다른 형식 인자나 지역 환경의 다른 변수의 값에 의존할 때 가끔 유용해요. 다음 예제에서 그런 경우를 볼 수 있어요. 여기서 단독으로 등장한 label은 다음 줄에서 x가 변경되기 전에 labelx의 값을 기반으로 만들어지도록 보장해요.

function(x, label = deparse(x)) {
    label
    x <- x + 1
    print(label)
}

프로미스의 표현식 슬롯은 그 자체로 다른 프로미스를 포함할 수 있어요. 이는 평가되지 않은 인자가 다른 함수의 인자로 전달될 때마다 발생해요. 프로미스를 강제 평가할 때, 그 표현식 안에 있는 다른 프로미스도 평가되면서 재귀적으로 강제 평가돼요.

더 알아보기 (Learn more)

출처: R Language Definition - 인자 평가