6.4 표현식 객체의 평가
6.4 표현식 객체의 평가
이번에는 expression 모드의 객체가 어떻게 평가되는지 알아볼게요. 표현식 객체는 호출 객체들의 리스트와 비슷하면서도, 평가 방식에서 독특한 성질을 갖고 있답니다.
출처: 문서
본문
6.4 표현식 객체의 평가
"expression" 모드의 객체는 Expression objects 섹션에서 정의돼요. 이들은 호출(call) 객체의 리스트와 아주 비슷하답니다.
> ex <- expression(2 + 2, 3 + 4)
> ex[[1]]
2 + 2
> ex[[2]]
3 + 4
> eval(ex)
[1] 7
표현식 객체를 평가하면 각 호출을 차례로 평가하지만, 최종 값은 마지막 호출의 값이라는 점에 주목하세요. 이런 점에서는 복합 언어 객체 quote({2 + 2; 3 + 4})와 거의 동일하게 동작해요. 그런데 미묘한 차이가 있어요. 호출 객체는 파스 트리에서 하위 표현식과 구별되지 않아요. 즉, 하위 표현식과 똑같은 방식으로 자동 평가된다는 뜻이죠. 반면 표현식 객체는 평가 과정에서 인식될 수 있고, 어떤 의미에서는 '인용된 상태'를 유지해요. 평가기는 표현식 객체를 재귀적으로 평가하지 않으며, 위처럼 eval 함수에 직접 전달했을 때만 평가해요. 그 차이는 이렇게 확인할 수 있어요.
> eval(substitute(mode(x), list(x = quote(2 + 2))))
[1] "numeric"
> eval(substitute(mode(x), list(x = expression(2 + 2))))
[1] "expression"
디파서(deparser)는 표현식 객체를 그것을 생성하는 호출로 표현해요. 이는 숫자형 벡터나 특별한 외부 표현이 없는 여러 다른 객체를 처리하는 방식과 비슷해요. 하지만 그 때문에 다음과 같은 혼란스러운 상황이 생기기도 하죠.
> e <- quote(expression(2 + 2))
> e
expression(2 + 2)
> mode(e)
[1] "call"
> ee <- expression(2 + 2)
> ee
expression(2 + 2)
> mode(ee)
[1] "expression"
즉, e와 ee는 출력했을 때 똑같아 보이지만, 하나는 표현식 객체를 생성하는 호출이고 다른 하나는 그 객체 자체라는 차이가 있어요.