Skip to content

Latest commit

 

History

History
78 lines (52 loc) · 2.6 KB

referential-transparency.md

File metadata and controls

78 lines (52 loc) · 2.6 KB

참조 투명성

정의. 표현식이 평가되는 결과로 바꿔도 프로그래밍의 동작이 변하지 않는다면 해당 표현식은 참조에 투명하다고 말합니다.

예제 (참조 투명성은 순수함수를 사용하는 것을 의미합니다)

const double = (n: number): number => n * 2

const x = double(2)
const y = double(2)

double(2) 표현식은 그 결과인 4로 변경할 수 있기에 참조 투명성을 가지고 있습니다.

따라서 코드를 아래와 같이 바꿀 수 있습니다.

const x = 4
const y = x

모든 표현식이 항상 참조 투명하지는 않습니다. 다음 예제를 봅시다.

예제 (참조 투명성은 에러를 던지지 않는것을 의미합니다)

const inverse = (n: number): number => {
  if (n === 0) throw new Error('cannot divide by zero')
  return 1 / n
}

const x = inverse(0) + 1

inverse(0) 는 참조 투명하지 않기 때문에 결과로 대체할 수 없습니다.

예제 (참조 투명성을 위해 불변 자료구조를 사용해야 합니다)

const xs = [1, 2, 3]

const append = (xs: Array<number>): void => {
  xs.push(4)
}

append(xs)

const ys = xs

마지막 라인에서 xs 는 초기값인 [1, 2, 3] 으로 대체할 수 없습니다. 왜냐하면 append 함수를 호출해 값이 변경되었기 때문입니다.

왜 참조 투명성이 중요할까요? 다음과 같은 것을 얻을 수 있기 때문입니다:

  • 지역적인 코드분석 코드를 이해하기 위해 외부 문맥을 알 필요가 없습니다
  • 코드 수정 시스템의 동작을 변경하지 않고 코드를 수정할 수 있습니다

문제. 다음과 같은 프로그램이 있다고 가정합시다:

// Typescript 에서 `declare` 를 사용하면 함수의 구현부 없이 선언부만 작성할 수 있습니다
declare const question: (message: string) => Promise<string>

const x = await question('What is your name?')
const y = await question('What is your name?')

다음과 같이 코드를 수정해도 괜찮을까요? 프로그램 동작이 변할까요?

const x = await question('What is your name?')
const y = x

보시다시피 참조 투명하지 않은 표현식을 수정하는 것은 매우 어렵습니다. 모든 표현식이 참조 투명한 함수형 프로그램에선 수정에 필요한 인지 부하를 상당히 줄일 수 있습니다.

(원문) In functional programming, where every expression is referentially transparent, the cognitive load required to make changes is severely reduced.