참조 투명성
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.
1. 개요
참조 투명성은 프로그래밍에서 표현식이 프로그램 내 어떤 위치에서든 그 값으로 대체될 수 있는 성질을 의미한다. 이는 표현식의 평가가 문맥에 의존하지 않고 독립적으로 이루어짐을 뜻하며, 수학적 연산과 같은 순수 함수는 참조 투명성을 갖는 반면, 변수 할당이나 상태에 의존하는 함수는 참조 불투명하다. 참조 투명성은 코드의 추론과 최적화를 용이하게 하지만, 명령형 프로그래밍 스타일의 표현을 어색하게 만들 수 있으며, 함수형 프로그래밍 언어에서 중요하게 다루어진다.
더 읽어볼만한 페이지
- 프로그래밍 언어 이론 - 튜링 완전
튜링 완전은 계산 이론에서 시스템이 튜링 기계와 동등한 계산 능력을 갖춰 튜링 기계가 계산할 수 있는 모든 함수를 계산하고 범용 튜링 기계를 시뮬레이션할 수 있음을 의미하며, 튜링 동등이라고도 한다. - 프로그래밍 언어 이론 - 부작용 (컴퓨터 과학)
함수의 반환값 외에 프로그램 상태를 변경시키는 부작용은 참조 투명성을 해치고 버그 발생 가능성을 높이며 최적화와 느긋한 계산법에 부정적 영향을 미치는 반면, 멱등성은 부작용이 있는 서브루틴을 여러 번 적용해도 시스템 상태에 단일 적용과 동일한 영향을 미치는 속성이다.
참조 투명성 | |
---|---|
개요 | |
학문 분야 | 전산 과학, 논리학, 수학, 철학 |
관련 개념 | 부작용 (컴퓨터 과학), 치환 모델, 수학 함수, 순수 함수, 순수성 (함수형 프로그래밍), 참값 보존 |
정의 | |
정의 | 동일한 입력에 대해 항상 동일한 출력을 생성하는 표현식 |
의미 | 프로그램의 동작이 표현식과 해당 값으로 대체될 때 변경되지 않는 속성 |
프로그래밍에서 사용 | |
함수형 프로그래밍 | 함수형 프로그래밍의 핵심 개념 |
중요성 | 프로그램 추론 및 최적화에 기여 |
장점 | 디버깅 용이 테스트 용이 병렬 처리 용이 |
특징 | |
특징 | 부작용 없음 외부 상태에 의존하지 않음 |
예시 | |
예시 | 수학 함수: f(x) = x * 2 순수 함수: 입력 값에만 의존하여 결과 생성 |
비고 | |
주의사항 | 참조 투명성을 위반하는 경우 예외 발생 가능 |
관련 개념 (심화) | |
관련 개념 | 지시 의미론 |
설명 | 표현식의 의미는 해당 값으로 완전히 결정됨 |
2. 역사
알프레드 노스 화이트헤드와 버트런드 러셀의 수학 원리(1910-13)에서 참조 투명성의 개념이 시작된 것으로 보인다.[3] 이들은 명제가 "투명하다"는 특징을 갖는다고 설명했는데, 이는 명제가 그 자체에 대해 말하는 것이 아니라, 그것을 통해 다른 무언가에 대해 말해진다는 것을 의미한다.[3]
어떤 표현식이 프로그램 내의 어떤 위치에서든 그 값으로 대체될 수 있다면, 그 표현식은 참조 상 투명하다고 한다. 이는 표현식의 평가가 문맥에 의존하지 않고 독립적으로 이루어진다는 것을 의미한다.[4]
이후 윌러드 밴 오먼 콰인은 그의 저서 단어와 대상(1960)에서 이 개념을 분석 철학에 도입했다.[1] 콰인은 단일 용어가 문장에서 순수하게 그 대상만을 지칭하고, 동일한 대상을 지칭하는 다른 용어로 대체해도 문장의 참값이 유지되는 경우를 "순수 지시적 위치"라고 정의했다.
크리스토퍼 스트레이치는 프로그래밍 언어의 기본 개념(1967)에서 이 용어를 프로그래밍 언어의 변수에 대한 논의에 사용하면서 현대 컴퓨터 과학 용어로 정립했다.[2] 스트레이치는 표현식의 값을 구할 때 하위 표현식의 값만 알면 되고, 내부 구조 등 다른 기능은 영향을 주지 않는 속성을 "지시적 투명성"이라고 불렀다.
3. 정의
형식 언어에서는 대체 가능성과 관련된 참조 투명성, 명확성, 전개 가능성과 같은 속성들이 정의된다.[4]
참조 투명성:
명확성:
전개 가능성:
참조 투명성, 명확성, 전개 가능성 간의 관계:
4. 예제와 반증
표현식과 관련된 모든 함수가 순수 함수라면, 그 표현식은 참조 상 투명하다. 순수하지 않은 함수라도 그 값이 무시되거나 부작용이 사소하다면 표현식에 포함될 수 있다.
예를 들어, 산술 연산은 참조 상 투명하다. 는 로 대체할 수 있다. 수학적 관점에서 모든 함수는 참조 상 투명하다. 는 특정 에 대해 항상 같은 결과를 반환하므로 투명하다.
반면 할당은 투명하지 않다. 예를 들어 C에서 은 변수 에 할당되는 값을 변경한다. 의 초기값이 10이라면, 이 표현식을 두 번 평가하면 각각 과 가 된다. 을 이나 로 대체하면 프로그램의 의미가 달라지므로, 이 표현식은 참조 상 투명하지 않다. 그러나 `int plusone(int x) { return x + 1; }`과 같은 함수 호출은 를 변경하지 않고 부작용이 없으므로 투명하다.
`today()`는 투명하지 않다. "Jan 1, 2001"로 대체하면 내일은 같은 값이 아니기 때문이다. 이는 상태(날짜)에 의존하기 때문이다.
하스켈처럼 부작용이 없는 언어에서는 모든 값 에 대해 이므로, 같은 것을 같은 것으로 대체할 수 있다. 부작용이 있는 언어에서는 이것이 불가능하다.
C 언어로 작성된 두 함수를 비교하면, 하나는 참조 투명하고(rt) 다른 하나는 참조 불투명하다(rq).
```c
int globalValue = 0;
int rq(int x)
{
globalValue++;
return x + globalValue;
}
int rt(int x)
{
return x + 1;
}
```
`rt`는 `x = y`일 때 `rt(x) = rt(y)`이므로 참조 투명하다. 예를 들어 `rt(6) = 7`, `rt(4) = 5`이다. 그러나 `rq`는 수정 가능한 전역 변수를 사용하므로 이에 대해 말할 수 없다.
`rq`의 참조 불투명성은 프로그램 추론을 어렵게 한다. 예를 들어 다음 구문을 보자.
`integer p = rq(x) + rq(y) * (rq(x) - rq(x));`
`rq(x)`가 매번 다른 값을 가질 수 있으므로, 이를 단순화하여 `rq(x)`로 만들 수 없다. `rq`는 전역 변수에 의존하기 때문에 `x - x = 0`과 같은 수학적 항등식이 유지되지 않는다.
5. 명령형 프로그래밍과의 대조
명령형 프로그래밍에서 표현식의 대체는 프로그램 실행의 특정 시점에서만 유효할 수 있다. 이러한 시퀀스 포인트의 정의와 순서는 명령형 프로그래밍의 이론적 기초이며 명령형 프로그래밍 언어 시맨틱의 일부이다.[1]
그러나 참조 투명한 표현식은 임의의 시점에 평가될 수 있으므로, 시퀀스 포인트 정의나 전체적인 평가 순서의 보장은 필요하지 않다. 이러한 것을 고려하지 않는 프로그래밍을 순수 함수형 프로그래밍이라고 부른다.[1]
참조 투명한 스타일의 코드 작성은 지능적인 컴파일러와 정적 코드 분석을 더 쉽게 하며, 자동으로 더 나은 코드 향상 변형을 가능하게 하는 장점이 있다. 예를 들어, C로 프로그래밍할 때 루프 내에서 비용이 비싼 함수 호출을 포함하는 경우, 함수 호출을 프로그램 결과에 영향 없이 루프 밖으로 빼더라도 성능 페널티가 발생한다. 프로그래머는 소스 코드 가독성을 희생하여 수동으로 코드 모션을 실행해야 할 수 있다. 하지만 컴파일러가 해당 함수 호출이 참조 투명하다는 것을 알 수 있다면, 이러한 변형을 자동으로 수행할 수 있다.[1]
참조 투명성을 강제하는 언어의 주요 단점은, 연속적인 단계를 갖는 명령형 프로그래밍 스타일에 자연스럽게 맞춰진 연산 표현식을 더 어색하고 덜 간결하게 만든다는 것이다. 그러한 언어들은 명확한 문법과 모나드와 같은 언어의 순수 함수 속성을 유지하면서도, 앞서 말한 작업들을 더 쉽게 만들기 위한 메커니즘을 종종 받아들인다.[1]
6. 기술적 과제와 해결
참조 상 투명한 표현식은 임의의 시점에 평가될 수 있으므로, 시퀀스 포인트 정의나 전체적인 평가 순서 보장은 필요하지 않다. 이러한 점을 고려하지 않는 프로그래밍을 순수 함수형 프로그래밍이라고 부른다.
참조 상 투명한 스타일의 코드 작성은 지능적인 컴파일러와 정적 코드 분석을 쉽게 하고, 자동으로 더 나은 코드 개선을 가능하게 한다. 예를 들어 C로 프로그래밍할 때, 루프 안에서 비용이 큰 함수를 호출하면 성능 저하가 발생할 수 있다. 이는 함수 호출을 프로그램 결과에 영향을 주지 않고 루프 밖으로 빼는 경우에도 마찬가지다. 프로그래머는 소스 코드 가독성을 희생하여 수동으로 코드를 옮겨야 할 수 있다. 그러나 컴파일러가 해당 함수 호출이 참조 상 투명하다는 것을 알 수 있다면, 이러한 변형을 자동으로 수행할 수 있다.[1]
참조 투명성을 강제하는 언어의 주요 단점은 연속적인 단계를 가지는 명령형 프로그래밍 스타일에 자연스럽게 맞춰진 연산 표현식을 더 어색하고 덜 간결하게 만든다는 것이다. 그러한 언어들은 명확한 문법과 모나드와 같은, 언어의 순수 함수적 성질을 유지하면서도 앞서 말한 작업들을 더 쉽게 만들기 위한 메커니즘을 도입하기도 한다.[1]
ML과 같이 기본적으로 함수형을 지향하지만 보조적으로 대입 기능도 갖추어, 식에 상태를 갖게 하는 경우가 종종 있다. Haskell에서는 모나드 형과 구문 설탕을 이용하여 참조 투명성을 유지한 채 절차형적인 표현을 가능하게 한다.[1] Clean에서는 한 번 참조하면 두 번 다시 참조하지 않는다는 일의성을 그 값의 타입에 부가 속성으로 부여하여, 대입을 이용하면서 참조 투명성을 유지하고, 효율화도 실현하고 있다.[1] Haskell 2010에서 ST 모나드(State Transformer 모나드)로 결실을 맺었다. 참조 투명성을 만족하는 함수는 인수가 같으면 같은 값을 반환하므로, 대입을 사용해도 그 성질을 만족하고, 다른 계산에도 영향을 미치지 않으면 된다. 이것이 ST 모나드이다.[1]
6. 1. 대입과 참조 투명성
하스켈과 같이 부작용이 없는 언어에서는 모든 값 에 대해 가 성립하므로, 어떤 표현식의 값을 같은 값으로 대체할 수 있다. 그러나 부작용이 있는 언어에서는 이것이 불가능하다. 값을 갖는 표현식의 대체가 프로그램 실행의 특정 시점에서만 유효하다면, 그 표현식은 참조 상 투명하지 않다. 이러한 시퀀스 포인트의 정의와 순서는 명령형 프로그래밍 언어의 시맨틱(semantics)의 일부이다.참조 투명한 표현식은 임의의 시점에 평가될 수 있으므로, 시퀀스 포인트 정의나 전체적인 평가 순서의 보장은 필요하지 않다. 이러한 점을 고려하지 않는 프로그래밍을 순수 함수형 프로그래밍이라고 부른다.
참조 투명성이 성립하는 언어에서는 변수의 값을 정의하는 구문은 있어도, 변수의 값을 재정의하는 '''대입'''(Assignment)을 수행하는 구문은 존재하지 않는다.[1] 이는 메모리 영역 관리에서 프로그래머의 개입을 줄여 표현을 간결하게 하지만, 실행 효율을 위한 언어 처리 시스템의 최적화가 중요하다.[1] 큰 데이터 구조 변경 시, 참조 투명성을 유지하면서 효율적으로 처리하는 방법이 필요하다.[1]
예를 들어, C 언어에서 `x = x + 1` 이라는 표현식은 변수 `x`에 할당되는 값을 변경한다. `x`의 초기값이 10이라고 가정하면, 이 표현식을 두 번 평가했을 때 각각 11과 12가 된다. `x = x + 1`을 11이나 12로 대체하면 프로그램의 의미가 달라지므로, 이 표현식은 참조 상 투명하지 않다. 그러나 `int plusone(int x) { return x + 1; }`과 같은 함수를 호출하는 것은 암시적으로 입력 `x`를 변경하지 않으며 부작용이 없으므로 참조 상 투명하다.
하스켈에서는 모나드 형과 구문 설탕을 이용하여 참조 투명성을 유지한 채 절차형적인 표현을 가능하게 한다.[1] 또한, Haskell 2010에서는 ST 모나드를 통해 대입을 사용하면서도 참조 투명성을 유지하고, 부작용으로부터 분리하는 방법을 제공한다.[1]
6. 2. 부작용과 참조 투명성
하스켈과 같이 부작용이 없는 언어에서는 모든 값 에 대해 가 성립하므로, 같은 값을 가지면 같은 것으로 대체할 수 있다. 그러나 부작용이 있는 언어에서는 이것이 불가능하다.[1]값을 가진 표현식의 대체가 프로그램 실행의 특정 시점에서만 유효하다면, 그 표현식은 참조 상 투명하지 않다. 이러한 시퀀스 포인트의 정의와 순서는 명령형 프로그래밍의 이론적 기초이며, 명령형 프로그래밍 언어 의미 체계의 일부이기도 하다.[1]
하지만 참조 상 투명한 표현식은 임의의 시점에 평가될 수 있으므로, 시퀀스 포인트 정의나 전체적인 평가 순서의 보장은 필요하지 않다. 이러한 점을 고려하지 않는 프로그래밍을 순수 함수형 프로그래밍이라고 부른다.[1]
참조 상 투명한 스타일로 코드를 작성하면 얻을 수 있는 장점은 다음과 같다. 먼저, 지능적인 컴파일러와 정적 코드 분석이 더 쉬워진다. 또한 자동으로 더 나은 코드 향상 변형이 가능해진다. 예를 들어 C로 프로그래밍할 때, 루프 내에서 비용이 비싼 함수를 호출하면 성능 페널티가 발생할 수 있다. 이는 함수 호출을 프로그램 결과에 영향을 주지 않고 루프 밖으로 빼는 경우에도 마찬가지다. 프로그래머는 소스 코드 가독성을 희생하여 수동으로 코드를 옮겨야 할 수도 있다. 그러나 컴파일러가 해당 함수 호출이 참조 상 투명하다는 것을 알 수 있다면, 이러한 변형을 자동으로 수행할 수 있다.[1]
반면 참조 투명성을 강제하는 언어는 연속적인 단계를 갖는 명령형 프로그래밍 스타일에 자연스럽게 맞춰진 연산 표현식을 더 어색하고 덜 간결하게 만든다는 단점이 있다. 그러한 언어들은 명확한 문법과 모나드와 같은, 언어의 순수 함수적 성질을 유지하면서도 앞서 말한 작업들을 좀 더 쉽게 만들기 위한 메커니즘을 도입하기도 한다.[1]
참조 투명성이 성립하는 언어에서는 공유된 메모리 영역에 저장된 값을 감시하는 코드를 작성할 수 없다. 이는 프로그램의 동작을 부작용에 대한 고려 없이 추적하고, 그 실행을 스케줄링할 수 있다는 점에서 프로그램 이해를 간단하게 하고 최적화 가능성을 넓힌다. 하지만 변수로 동기를 맞추는 것과 같은 간단한 병행·병렬 처리 프로그램은 더 이상 작성할 수 없으며, 입력 동작을 표현하기 위해서는 다양한 방법이 필요하다. 또한 스케줄링에 영향을 받지 않도록 출력을 순서대로 수행하기 위해서도 여러 가지 방법을 고려해야 한다.[1]
6. 3. 해결 방안
ML은 기본적으로 함수형 프로그래밍 언어이지만, 보조적으로 대입 기능을 갖추어 변수의 값을 변경하고 상태를 표현할 수 있도록 한다. Haskell에서는 '''모나드'''(Monad) 형과 구문 설탕을 이용하여 참조 투명성을 유지하면서 절차형 프로그래밍과 유사한 표현을 가능하게 한다. Clean은 값의 타입에 일의성(uniqueness)이라는 부가 속성을 부여하여 대입을 사용하면서도 참조 투명성을 유지하고 효율성을 높이는 방법을 사용한다.Haskell은 ST 모나드(State Transformer 모나드)를 통해 대입을 사용하면서도 참조 투명성을 유지하고 다른 계산에 영향을 주지 않는 방법을 제공한다. 예를 들어, 재귀 함수는 대입을 사용한 반복으로 구현하더라도 주어진 인수가 같으면 항상 같은 결과를 반환한다. ST 모나드는 대입을 함수의 내부에서만 유지하고, 결과는 변수의 내용을 복사하여 반환하는 함수를 사용함으로써 부작용을 분리한다.[1]
7. 관련 개념
- 멱등성: 연산을 여러 번 적용해도 결과가 달라지지 않는 성질이다.
- 리스코프 치환 원칙: 객체 지향 프로그래밍에서 하위 타입 객체가 상위 타입 객체를 대체할 수 있어야 한다는 원칙이다.
- 재작성 규칙: 표현식을 동등한 다른 표현식으로 바꾸는 규칙이다.
- 함수형 프로그래밍 언어: 부작용이 없는 순수 함수를 중심으로 하는 프로그래밍 패러다임이다.
- 분산 처리: 여러 컴퓨터에 작업을 분산하여 처리하는 방식이다.
- 메모이제이션: 함수의 결과를 캐싱하여 동일한 입력에 대한 반복 계산을 피하는 기법이다.
참조
[1]
서적
Word and Object
https://archive.org/[...]
MIT Press
1960
[2]
간행물
Fundamental Concepts in Programming Languages
1967
[3]
서적
Principia Mathematica
https://archive.org/[...]
Cambridge University Press
1927
[4]
논문
Referential Transparency, Definiteness and Unfoldability
http://www.itu.dk/pe[...]
1990
본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.
문의하기 : help@durumis.com