FP - 참조 투명성(Referential Transparency)

Keunjae Song·2020년 3월 13일
0

fp

목록 보기
3/6

스칼라로 배우는 함수형 프로그래밍을 읽고 정리한 글입니다.

이 글에서는 fp의 참조 투명성(referencial transparency) 개념에 대해 소개합니다.

이전 글을 통해 부수 효과(side effect)가 있는 함수는 비순수 함수(non-pure function)라고 하고, 그와 반대로 부수 효과가 없는 함수는 순수 함수(pure function)라고 칭하는 것을 알게 되었습니다.

순수 함수에 대한 추가적인 설명

결국 순수 함수는 어떠한 입력을 가지고 뭔가를 계산하여 출력을 내놓는 것 이외에는 추가적인 작업(side effect)을 수행하지 않는다.
또한, "같은 입력에 대해서는 항상 같은 출력을 내놓는다"가 중요한 전제인데,
정수에 대한 더하기(+) 함수를 생각해보면 입력으로 오는 좌우 두 정수에 대해서 항상 같은 값을 돌려준다.
2 + 3을 백번 해도 매번 결과는 무조건 5지, 6이진 않지 않은가.

참조 투명성의 개념

여기서 만약, 코드 중에 2 + 3 표현식(expression)을 모두 해당 표현식의 결과인 5로 치환하면 어떻게 될까?
당연히 아무 문제 없고 똑같이 잘 동작한다.

이처럼 표현식을 해당 표현식의 평가(evaluation) 결과로 대체해도 프로그램에 아무런 지장을 미치지 않는다면, 해당 표현식을 참조에 투명하다라고 한다.

참조 투명성과 함수 순수성의 관계

"참조에 투명한 모든 x에 대해 표현식 f(x)가 참조에 투명하면 함수 f는 순수하다"라는 중요한 개념이 있다.

문장만 봐서는 무슨 뜻인지 잘 모르곘으므로 예제를 살펴보도록 하자.

def buyCoffee(cc: CreditCard): Coffee = {
  val cup = new Coffee()
  cc.charge(cup.price) // 신용카드 대금 청구
  cup
}

위와 같이 커피를 구매하는 buyCoffee 함수가 있다고 하자.
이 함수는 Coffee를 반환하고 cc.charge(cup.price)에서 신용카드 대금 청구가 발생한다.

여기서 buyCoffee(aliceCreditCard)의 평가 결과는 cup이며, 이는 new Coffee()와 동등하다.
그렇다면 임의의 p에 대해서 p(buyCoffee(aliceCreditCard)p(new Coffee())는 동일하게 작동할까?

그렇지 않다.

buyCoffee(aliceCreditCard)는 신용카드 회사에 컨택해 대금을 청구하지만,
new Coffee()는 Coffee 객체를 생성할 뿐, 대금을 청구하지 않는다.
이처럼 표현식 buyCoffee(aliceCreditCard)는 해당 표현식의 평가 결과인 new Coffee()로 대체할 경우, 같은 동작(결과)이 나타나지 않으므로 참조에 투명하지 않다.

그렇기에, 표현식에 사용된 buyCoffee 함수는 순수하지 않다 즉, 비순수 함수이다라는 결론에 도달할 수 있게 된다.

1개의 댓글

comment-user-thumbnail
2023년 8월 2일

좋은 정보 감사합니다!

답글 달기