참조 투명성은 무엇입니까?


285

어떤 용어 않습니다 참조 투명도 평균을? 나는 그것이 "당신이 동등한 것을 동등한 것으로 대체 할 수 있다는 것을 의미한다"는 것을 들었다. 그러나 이것은 부적절한 설명처럼 보인다.


1
와우, 왜이 질문의 인기가 갑자기 급증하는지 궁금합니다.
Claudiu

1
@claudia : 확실하게 말할 수는 없지만, r / haskell 은 바람이 불었고 많은 사람들이 Uday가 꽤 정확하지만 커뮤니티에서 약간의 지브를 얻는다고 느꼈습니다.
efrey

6
@efrey 지브, 아마도 그랬을 것입니다. 그러나 함수형 프로그래머가 명령형 프로그래밍 언어와 부작용이있는 함수형 언어 (Lisp 및 ML과 같은)가 참조 적으로 투명하지 않다고 주장하면서 지브를 취하지 않습니까? 그렇게하기 전에 최소한 사실을 알아야하지 않습니까?
Uday Reddy

2
@Claudiu 나는 Haskell Reddit에 그것을 게시하고 있으며 Conal은 그것을 트윗했습니다. 나는 토론이 흥미롭고 더 넓은 토론을 할만한 가치가 있다고 생각했다. 나는 토론을 자극하기 위해 Uday의 지브에 주목했다. 우리는 FPers가 때때로 만족스럽고 좋은 제품을 필요로 할 수 있다는 데 동의합니다.
chrisdornan

7
@efrey. 사실, 나는 두 번째 게시물에서 Bird and Wadler (의미론가?)를 인용하기로 선택한 이유입니다. 지식이 풍부한 사람들은 참조 투명성에 대한 대중적인 개념이 모호하고 일관성이 없다는 것을 알고 있습니다. 그러나 프로그래밍 커뮤니티에 제대로 설명되지 않았습니다. 바라건대 내 글이 변화를 가져 오기를 바랍니다.
Uday Reddy

답변:


362

"참조 투명성"이라는 용어는 분석 철학 , 논리 및 수학의 방법에 기초하여 자연어 구성, 진술 및 인수를 분석하는 철학의 지점 에서 유래 합니다. 다시 말해, 컴퓨터 과학 이외의 언어 는 우리가 프로그래밍 언어 의미론에 가장 가까운 주제 입니다. 철학자 윌러드 퀸 (Willard Quine) 은 참조 투명성의 개념을 시작하는 책임을 맡았지만 베르트랑드 러셀 (Bertrand Russell)과 알프레드 화이트 헤드 (Alfred Whitehead)의 접근에도 암시 적이었다.

핵심적으로 "참조 투명성"은 매우 간단하고 명확한 아이디어입니다. "참조"라는 용어는 분석 철학에서 표현 이 말하는 것에 대해 이야기하는 데 사용 됩니다 . 프로그래밍 언어 의미에서 "의미"또는 "표시"가 의미하는 것과 거의 같습니다. Andrew Birkett의 예제 ( 블로그 게시물 )를 사용하여 "스코틀랜드의 수도"라는 용어는 에든버러시를 나타냅니다. 이것이 "참조"의 간단한 예입니다.

해당 문맥의 용어를 동일한 엔티티나타내는 다른 용어로 대체해도 의미가 바뀌지 않으면 문장의 문맥은 "참조 적으로 투명"합니다 . 예를 들어

스코틀랜드 의회는 스코틀랜드의 수도에서 만납니다.

와 같은 의미

스코틀랜드 의회는 에든버러에서 열린다.

따라서 "스코틀랜드 의회는 ...에서 만나다"라는 문맥은 참조 적으로 투명한 맥락입니다. 의미를 바꾸지 않고 "스코틀랜드의 수도"를 "에든버러"로 바꿀 수 있습니다. 다른 말로 표현하자면, 문맥은 그 용어가 무엇을 의미하는지에 대해서만 관심을 갖습니다. 그것이 문맥이 "참조 적으로 투명"하다는 의미입니다.

반면에, 문장에서

에든버러는 1999 년부터 스코틀랜드의 수도였습니다.

우리는 그러한 교체를 할 수 없습니다. 우리가 그렇게한다면, "에딘버러는 1999 년부터 에든버러였습니다."라는 말을들을 수있을 것입니다. 따라서 "에딘버러는 1999 년 이래로 ..."라는 문맥이 참조 적으로 불투명 한 것 같습니다 (참조 적으로 투명한 것과 반대). 그것은 용어가 말하는 것보다 더 많은 것에 관심 이 있습니다. 무엇입니까?

"스코틀랜드의 수도"와 같은 것은 명확한 용어 로 불리며 오랫동안 논리 학자와 철학자들에게 적은 양의 고통을주지 않았습니다. Russell과 Quine은 그들이 실제로 "참조 적"이 아니라고 말하면서 그것들을 정리했다. 즉, 위의 예들이 실체를 언급하는데 사용되었다고 생각하는 것은 잘못이다. "에딘버러는 1999 년 이래로 스코틀랜드의 수도였습니다."를 이해하는 올바른 방법은

스코틀랜드는 1999 년부터 수도를 보유하고 있으며 그 수도는 에든버러입니다.

이 문장은 너트로 변환 될 수 없습니다. 문제 해결됨! Quine의 요점은 자연어는 실제 사용에 편리하도록 만들어 졌기 때문에 복잡하거나 적어도 복잡하다고 말했지만 철학자와 논리학자는 올바른 방식으로 이해함으로써 명확성을 가져와야합니다. 참조 투명성은 의미를 명확하게하기 위해 사용되는 도구 입니다.

이 모든 것이 프로그래밍과 관련이 있습니까? 실제로는별로 없습니다. 우리가 말했듯이, 참조 투명성은 언어를 이해하는 데, 즉 의미 를 할당 하는 데 사용되는 도구 입니다. 프로그래밍 언어 시맨틱 분야를 설립 한 Christopher Strachey 는이를 의미 연구에 사용했습니다. 그의 기본 논문 인 " 프로그래밍 언어의 기본 개념 "은 웹에서 구할 수 있습니다. 그것은 아름다운 종이이며 모두가 읽고 이해할 수 있습니다. 그러니 제발 그렇게 해주세요 당신은 많이 깨달을 것입니다. 그는이 단락에서 "참조 투명성"이라는 용어를 소개합니다.

식의 가장 유용한 속성 중 하나는 Quine 참조 투명성에 의해 호출되는 것입니다. 본질적으로 이것은 하위 표현식을 포함하는 표현식의 값을 찾으려면 하위 표현식에 대해 알아야 할 것은 그 값뿐입니다. 내부 구조, 구성 요소의 수 및 특성, 평가 순서 또는 작성되는 잉크의 색상과 같은 하위 표현의 다른 기능은 기본 값과 관련이 없습니다. 표현.

"본질적으로"의 사용은 Strachey가 간단한 용어로 설명하기 위해 그것을 변형시키고 있음을 시사합니다. 기능 프로그래머는이 단락을 자신의 방식으로 이해하는 것 같습니다. 이 논문에는 "참조 투명성"이 9 가지나 있지만 다른 것에 대해서는 신경 쓰지 않는 것 같습니다. 실제로 Strachey의 전체 논문은 명령형 프로그래밍 언어 의 의미를 설명하는 데 전념하고 있습니다 . 그러나 오늘날 기능 프로그래머는 명령형 프로그래밍 언어가 그렇지 않다고 주장합니다. 참조 적으로 투명 . Strachey는 그의 무덤에서 돌고있을 것입니다.

상황을 구할 수 있습니다. 우리는 자연어는 실제 사용하기 편리하도록 만들어 졌기 때문에 "지저분하거나 복잡하다"고 말했다. 프로그래밍 언어는 같은 방식입니다. 그것들은 실제 사용에 편리하도록 만들어 졌기 때문에 "지저분하거나 적어도 복잡하다". 그렇다고 그들이 우리를 혼동해야한다는 의미는 아닙니다. 의미가 명확하도록 참조가 투명한 메타 언어를 사용하여 올바른 방식으로 이해해야합니다. 내가 인용 한 논문에서 Strachey는 정확히 그렇게합니다. 그는 명령형 프로그래밍 언어를 기본 개념으로 세분화하여 어디에서나 명확성을 잃지 않도록하여 프로그래밍 언어의 의미를 설명합니다. 그의 분석에서 중요한 부분은 프로그래밍 언어의 표현식에는 두 가지 종류의 "값"이 있다는 점을 지적하는 것입니다.r- 값 . Strachey의 논문이 있기 전에, 이것은 이해되지 않았고 혼란이 최고를 지배했다. 오늘날 C의 정의는 일상적으로 C를 언급하며 모든 C 프로그래머는 그 차이를 이해합니다. (다른 언어로 된 프로그래머가 그것을 잘 이해하기는 어렵습니다.)

Quine과 Strachey는 어떤 형태의 상황 의존성을 수반하는 언어 구성의 의미에 관심을 가졌습니다. 예를 들어, "에딘버러는 1999 년 이후 스코틀랜드의 수도였습니다"라는 예는 "스코틀랜드의 수도"가 고려되는 시간에 의존한다는 사실을 나타냅니다. 이러한 상황 의존성은 자연 언어와 프로그래밍 언어 모두에서 현실입니다. 함수형 프로그래밍에서도 자유 변수와 바운드 변수는 변수가 나타나는 컨텍스트와 관련하여 해석됩니다. 어떤 종류의 컨텍스트 종속성은 어떤 방식 으로든 참조 투명성을 차단합니다. 용어가 의존하는 문맥에 관계없이 용어의 의미를 이해하려고하면 혼동이 생길 수 있습니다. Quine는 모달 논리의 의미에 관심이있었습니다. 그는 그것을 개최모달 로직 은 참조 용으로 불투명했으며 참조 용으로 투명한 프레임 워크로 변환하여 정리해야합니다 (예 : 필요에 따라 가능성으로 간주). 그는이 논쟁을 크게 잃었다. 논리 학자와 철학자들은 모두 Kripke의 가능한 세계 의미론이 완벽하게 적합하다는 것을 발견했습니다. 비슷한 상황은 명령형 프로그래밍과도 관련이 있습니다. Strachey에 의해 설명 된 국가 의존성과 Reynolds에 의해 설명 된 상점 의존성 (Kripke의 가능한 세계 의미와 유사한 방식)은 완벽하게 적합합니다. 기능 프로그래머는이 연구에 대해 잘 모릅니다. 참조 투명성에 대한 그들의 아이디어는 큰 소금 알갱이로 취해야합니다.

[추가 정보 : 위의 예는 "스코틀랜드의 수도"와 같은 간단한 문구가 여러 수준의 의미를 가짐을 보여줍니다. 한 수준에서, 우리는 현재의 수도에 대해 이야기하고있을 것입니다. 다른 차원에서, 우리는 스코틀랜드가 시간이 지남에 따라 가질 수 있었던 모든 가능한 수도에 대해 이야기 할 수 있습니다. 우리는 특정 상황을“확대”하고“확대”하여 일반적인 상황에서 모든 문맥을 아주 쉽게 확장 할 수 있습니다. 자연어의 효율성은 그렇게하는 우리의 능력을 활용합니다. 명령형 프로그래밍 언어는 거의 같은 방식으로 효율적입니다. 과제의 오른쪽에 변수 x 를 사용하여 ( r-value ) 특정 상태에서의 값에 대해 이야기 할 수 있습니다. 또는 우리는 그것의 l- 값에 대해 이야기 할 수 있습니다이는 모든 주에 걸쳐 있습니다. 사람들은 그런 것들로 혼동되는 경우가 거의 없습니다. 그러나 언어 구성에 내재 된 모든 의미의 계층을 정확하게 설명 할 수도 있고 그렇지 않을 수도 있습니다. 그러한 의미의 모든 층이 반드시 '분명한'것은 아니며 그것들을 올바르게 연구하는 것은 과학의 문제입니다. 그러나 이러한 계층 적 의미를 설명하는 평범한 사람들의 인공 지능은 그들이 그들에 대해 혼동한다는 것을 의미하지는 않는다.]

아래의 별도의 "postscript"는이 논의를 기능적 및 명령형 프로그래밍과 관련이 있습니다 .


10
고맙지 만, 평등이라는 '명백한'확장 개념이 있다고 생각하지 않습니다. "스코틀랜드의 수도"는 에든버러시를 의미한다고 말했을 때, 당신은 그것에 대해 두 번 생각하지 않았습니다. 그러나 "1999 년 이후"에 대해 이야기하기 시작했을 때 갑자기 시간이 걸린다는 것을 알게되었습니다. 따라서 평등의 확장 개념은 미묘 할 수 있으며 프로그래밍 언어 연구자들에 의해 공식화됩니다. 확장 평등에 대한 완벽한 이해를 원하는 사람들은 그 연구의 결과를 배워야합니다. 전혀 '분명하지'않을 수도 있습니다.
Uday Reddy

5
환상적인! RT에 대한 대중의 오해를 반갑게 환영합니다 (예 : 기능 과 연계) . 또는 식과 값이 다른 종류이기 때문에 식을 값으로 대체하여 정의 할 수 있습니다 (위키 백과 동일). 명령형 언어의 RT-ness를 고려할 때 사람들이 잘못하는 곳은 아마도 이러한 "값"은 상점의 함수와 같이 더 복잡한 것보다는 숫자와 같은 단순한 것입니다.
Conal

13
@sclv 컴퓨터 과학에 대한 분석 철학의 광범위한 영향에 관해서는, 우리가 알고있는 컴퓨터 과학은 Godel, Church, Kleene 및 Turing에 의해 설립되었다고 말해야합니다. 이 사람들은 논리 학자 였고 논리의 수학적, 철학적 측면, 특히 Peano, Frege, Russell, Whitehead, Carnap 및 Quine의 전통에 정통했습니다. 현대 컴퓨터 과학의 초기 개척자들은 그 관계를 알고있었습니다. 그러나 컴퓨터 과학의 급속한 성장은 그것들을 단절시켰다. 우리는 그들에게 돌아 가야합니다.
Uday Reddy

5
@sclv Logic은 전통적으로 결과 의 과학으로 해석됩니다 . 그러나 나는 그것이 더 넓다고 생각합니다. 정보 과학입니다 . Quine, 나는 더 넓은 견해를 가져온 최초의 사람으로 본다. "단어 및 대상"은 자연어 문장의 정보 내용을 분석 한 것입니다. 그러나 철학자와 수학자 모두 계산에 적극적으로 관심을 가지지 않았는데 , 그것은 태초부터 문명과 과학을위한 중앙 계산이 얼마나 중앙 집중적 계산 이었는지를 감안할 때 상당히 복잡하다. 우리는 그들이 관심을 가질 수있는 방법을 찾아야합니다.
Uday Reddy

3
@Conal : 요점을 증폭시키는 새로운 답변을 추가했습니다. 아마도 페이지의 맨 아래에있을 것입니다.
Uday Reddy

134

함수형 프로그래밍에서 일반적으로 사용되는 용어 인 참조 투명도는 함수와 입력 값이 주어지면 항상 동일한 출력을 수신한다는 것을 의미합니다. 즉, 함수에 사용 된 외부 상태가 없습니다.

다음은 참조 투명 함수의 예입니다.

int plusOne(int x)
{
  return x+1;
}

입력과 함수가 주어지면 참조 투명 함수를 사용하면 함수를 호출하는 대신 값으로 대체 할 수 있습니다. 따라서 매개 변수 5로 plusOne을 호출하는 대신 6으로 대체 할 수 있습니다.

또 다른 좋은 예는 일반적으로 수학입니다. 함수와 입력 값이 주어진 수학에서는 항상 동일한 출력 값에 매핑됩니다. f (x) = x + 1. 그러므로 수학의 함수는 참조가 투명합니다.

이 개념은 참조 적으로 투명한 기능이있을 때 자동 병렬화 및 캐싱이 쉬워지기 때문에 연구자에게 중요합니다.

참조 투명도는 항상 Haskell과 같은 기능적 언어에서 사용됩니다.

-

대조적으로 참조 불투명의 개념이 있습니다. 이것은 반대를 의미합니다. 함수를 호출하는 것이 항상 동일한 출력을 생성하지는 않습니다.

//global G
int G = 10;

int plusG(int x)
{//G can be modified externally returning different values.
  return x + G;
}

또 다른 예는 객체 지향 프로그래밍 언어의 멤버 함수입니다. 멤버 함수는 일반적으로 멤버 변수에서 작동하므로 참조 불투명합니다. 물론 멤버 함수는 참조 적으로 투명 할 수 있습니다.

또 다른 예는 텍스트 파일에서 읽고 출력을 인쇄하는 함수입니다. 이 외부 텍스트 파일은 언제든지 변경 될 수 있으므로이 함수는 참조 적으로 불투명합니다.


1
참고로 투명한 멤버 함수를 사용하여 완전히 참조 가능한 투명한 객체를 가질 수 있습니다. 참조 okmij.org/ftp/Scheme/oop-in-fp.txt
조나단 Arkell에게

1
이 기사에서 다루고있는 코드는 다음과 같습니다. okmij.org/ftp/Scheme/pure-oo-system.scm
Jonathan Arkell

완전히 참조가 투명한 클래스의 경우 모든 멤버 함수가 정적 일 수 있습니다.
Brian R. Bondy

13
여기서 말하는 것은 참조 투명성 이 아니라 일반적으로 그렇게 말하는 것입니다. Uday의 두 가지 답변과 이에 대한 의견을 참조하십시오. 특히, "출력"이라고 부르는 것은 주석이 아닙니다. "plusG 3"을 동일한 값 / 표시가있는 다른 표현식으로 바꾸면 실제로 같은 의미의 프로그램을 얻게되므로 RT는 명령형 언어로 유지됩니다. "3 + 10"또는 "13"표현 은 "plusG 3"과 같은 의미를 갖지 않습니다 . 명령형 언어의 의미는 "저장소"(상태)의 기능이기 때문입니다.
Conal

1
부작용과 상태 변경에 대한 기사를 읽었으며 RT와 관련이 있다는 직관을 얻었습니다. 메모를 추가해 주시겠습니까?
Gaurav

91

참조 적으로 투명한 기능은 입력에만 의존하는 기능입니다.


4
객체가 상태를 가지고 있기 때문에 OO 프로그래밍이 어려운 이유입니다.
Kris

5
함수를 설명 할 때 "참조 투명"이 "결정적"과 동일하다고 말하는 것이 맞습니까? 그렇지 않은 경우 두 용어의 차이점은 무엇입니까?
mwolfe02

1
이것은 "순수한"기능의 정의처럼 들립니다.
Evgeny A.

75

[이것은 함수 / 제한 프로그래밍의 문제에 대한 토론에 더 가까이 다가 가기 위해 3 월 25 일부터 제 대답에 대한 포스트 스크립트입니다.]

함수형 프로그래머의 참조 투명성에 대한 아이디어는 세 가지 측면에서 표준 개념과 다른 것 같습니다.

  • 철학자 / 논리학자는 "참조", "표시", "designatum"및 " 베 두둥 "(Frege의 독일 용어)과 같은 용어를 사용하지만 기능 프로그래머는 "값"이라는 용어를 사용합니다. Landin, Strachey 및 그 후손들도 "값"이라는 용어를 사용하여 참조 / 표시에 대해 언급 한 것을 알 수 있습니다. 이는 Landin과 Strachey가 도입 한 용어를 단순화 한 것일 수 있습니다. 순진한 방식으로 사용하면 큰 차이가 있습니다.)

  • 기능 프로그래머는 이러한 "값"이 외부가 아닌 프로그래밍 언어 내에 존재한다고 생각합니다. 이 과정에서 그들은 철학자와 프로그래밍 언어 의미 론자와는 다릅니다.

  • 그들은이 "값들"이 평가에 의해 얻어 져야한다고 믿는 것 같습니다.

예를 들어, 참조 투명성 에 관한 Wikipedia 기사 는 다음과 같이 말합니다.

표현식은 프로그램의 동작을 변경하지 않고 값으로 대체 할 수있는 경우 참조 적으로 투명하다고합니다 (즉, 동일한 효과를 가지며 동일한 입력에서 출력되는 프로그램을 생성 함).

이것은 철학자 / 논리 학자들이 말하는 것과 완전히 다릅니다. 그들은 문맥에서 표현 이 같은 것을 가리키는 다른 표현 ( 핵심 표현) 으로 대체 될 수 있다면 문맥이 참조 적이거나 참조 적으로 투명 하다고 말한다 . 이 철학자 / 의학자는 누구입니까? 그들은 Frege , Russell , Whitehead , Carnap , Quine를 포함합니다 , Church를 포함합니다.그리고 수많은 다른 사람들. 그들 각각은 우뚝 솟은 인물입니다. 이 논리 학자들의 결합 된 지적 능력은 가장 말이별로 없다. 그들 모두는 지시 대상 / 외연 만 이야기 할 수있는 언어 내에서 공식 언어와 표현 밖에 존재하는 위치에서 만장일치 있습니다 에 대해 그들. 따라서 언어 내에서 할 수있는 모든 것은 한 표현을 동일한 엔터티를 나타내는 다른 표현으로 바꾸는 것입니다. 참조 / 표시 자체 언어 내에 존재 하지 않습니다 . 기능 프로그래머가이 잘 확립 된 전통에서 벗어난 이유는 무엇입니까?

프로그래밍 언어 의미 론자들이 그것들을 잘못 이해했을 수도 있습니다. 그러나 그들은하지 않았다.

랜딘 :

(a) 각 표현에는 중첩 된 부분 표현 구조가 있고, (b) 각 부분 표현은 무엇인가 (보통 숫자, 진리 값 또는 숫자 함수)를 나타냅니다. (c) 표현이 나타내는 것, 즉 "값"은 하위 속성의 다른 속성이 아닌 하위 표현식의 값. [추가 강조]

스토이 :

표현식에서 중요한 것은 값이며 하위 표현식은 다른 값 으로 대체 될 수 있습니다 [추가 강조]. 더욱이, 표현의 가치는 특정 한계 내에서 발생할 때마다 동일하다 ".

새와 물레 :

표현의 가치는 그것의 구성 적 표현의 가치 (만약 있다면)의 가치에만 의존하며, 이러한 부분 표현 은 같은 가치를 갖는 다른 표현으로 자유롭게 대체 될 수있다 [추가 강조].

따라서 돌이켜 보면 "참조"/ "표시"를 "값"으로 대체하여 용어를 단순화하려는 Landin과 Strachey의 노력은 해로울 수 있습니다. "가치"에 귀를 기울이자 마자 평가 과정을 생각하는 유혹이 있습니다. 그것이 평가가 아니라는 것이 명백 할지라도, 평가가 생산하는 것을 "가치"로 생각하는 것도 마찬가지로 유혹적이다. 그것이 내가 기능 프로그래머의 눈에 "참조 투명성"이라는 개념에 일어났던 것입니다. 그러나 초기 semanticists에 의해 언급되고 있던 "값이" 하지 평가 또는 함수의 출력 또는 그러한 일의 결과. 그것은 용어의 의미입니다.

우리가 복잡한 수학적 / 개념적 대상으로서 표현의 소위 "가치"(고전 철학자들의 담론에서 "참조"또는 "표시")를 이해하면 모든 종류의 가능성이 열린다.

  • 명령형 프로그래밍 언어에서 Strachey는 변수를 L- 값 으로 해석했습니다.3 월 25 일 답변에서 언급했듯이 . 이는 프로그래밍 언어의 구문 내에서 직접 표현할 수없는 정교한 개념적 객체입니다.
  • 또한 구문 내에서 "값"이 아닌 복잡한 수학 객체의 또 다른 인스턴스 인 상태 간 함수와 같은 언어로 명령을 해석했습니다.
  • C에서 부작용을 일으키는 함수 호출조차도 상태를 상태 변환기로 잘 정의 된 "값"을 갖습니다 (기능 프로그래머 용어에서 소위 "모 노드").

함수형 프로그래머가 그러한 언어를 "참조 적으로 투명"하다고 부르기를 꺼리는 것은 복잡한 수학 / 개념적 객체를 "값"으로 인정하는 것을 꺼려한다는 것을 의미한다. 다른 한편으로, 그들은 그들 자신이 가장 좋아하는 구문에 넣고 "monad"와 같은 버즈 단어로 차려 입었을 때 상태 변환기를 "값"이라고 부르는 것 같습니다. "참조 투명성"에 대한 그들의 생각이 일관성이 있다고 그들에게 부여하더라도 그것들이 완전히 일치하지 않는다고 말해야합니다.

약간의 역사는 이러한 혼란이 어떻게 생겼는지에 대해 약간의 빛을 던질 수 있습니다. 1962 년에서 1967 년 사이의 기간은 Christopher Strachey에게는 매우 집중적 인시기였습니다. 1962-65 년 사이에 Maurice Wilkes의 연구 조교로 아르바이트를하면서 CPL로 알려진 프로그래밍 언어를 디자인하고 구현했습니다. 이것은 필수적인 프로그래밍 언어이지만 강력한 기능적 프로그래밍 언어 기능도 갖추어야합니다. 컨설팅 회사에서 Strachey의 직원 인 Landin은 Strachey의 프로그래밍 언어에 큰 영향을 미쳤습니다. 1965 년 랜드 마크인 " Next 700 프로그래밍 언어 "에서 Landin은 기능적 프로그래밍 언어를 독창적으로 홍보합니다. 표시).언어) 및 명령형 프로그래밍 언어를 "반대로"설명합니다. 다음 논의에서 우리는 Strachey가 Landin의 강력한 입장에 의구심을 제기하는 것을 발견했습니다.

... DL은 모든 언어의 하위 집합을 형성합니다. 그것들은 흥미로운 부분 집합이지만, 익숙하지 않으면 사용하기 불편합니다. 우리 는 현재 명령과 점프를 포함한 언어로 증거를 구성하는 방법을 모르기 때문에 그것들이 필요 합니다. [추가 강조]

1965 년 Strachey는 Oxford에서 독자 직을 맡았으며 본질적으로 명령과 점프 이론을 개발하는 데 전일제로 일한 것 같습니다. 1967 년, 그는 코펜하겐 여름 학교에서 " 프로그래밍 언어의 기본 개념 "에 대한 강의에서 이론을 준비했습니다 . 강의 노트는 출판 되었어야했지만 불행히도 확장 편집으로 인해 진행 과정이 구체화되지는 않았다. 그러나 옥스포드에서의 Strachey의 많은 작업과 마찬가지로이 논문은 사적인 영향력을 행사했다. " ( 마틴 캠벨 켈리 )

Strachey의 저술을 얻는 데 어려움이 있었기 때문에 사람들은 2 차 자료와 의견에 의존하여 혼란을 전파 할 수있었습니다. 그러나 이제 " 기본 개념 "을 웹에서 쉽게 사용할 수 있으므로 작업을 추측하기 위해 의지 할 필요가 없습니다. 우리는 그것을 읽고 Strachey가 의미하는 바에 대해 우리 자신의 마음을 구성해야합니다. 특히:

  • 3.2 절에서 그는 "R- 값 참조 투명성"에 대해 말하는 "표현"을 다룬다.
  • 그의 섹션 3.3은 "L- 값 참조 투명성"에 대해 말하는 "명령"을 다루고 있습니다.
  • 3.4.5 절에서 그는 "함수와 루틴"에 대해 이야기하고 "R- 값 맥락에서 R- 값 참조 투명도의 이탈은 표현을 여러 명령과 간단한 표현으로 분해하여 제거해야한다고 선언합니다. 이것은 의견의 주제로 어려운 것으로 판명되었습니다. "

명령형 프로그래머의 개념적 세계를 채우는 L- 값, R- 값 및 기타 복잡한 개체 간의 차이를 이해하지 않고 "참조 투명성"에 대한 이야기는 근본적으로 잘못됩니다.


10
"값"(평가 대 표기법)이라는 두 가지 개념을 혼동하면 기능 프로그래머가 명령 언어 에 대한 비판에서 오해를 불러 일으킨다는 점을 강조 할 가치가 있다고 생각합니다 .
Conal

8
즉, 평가 개념은 명령형 언어는 RT가 아니라고 표기법은 그렇지 않다는 결론에 이른다.
Conal

12
언어의 표기 의미를 완전히 파악한 후에는 참조가 투명 해지지 만 도움이되지 않는 것 같습니다. 따라서 이것은이 용어가 프로그래밍 언어와 관련하여 유용하지 않다고 말하는 것보다 중요합니다.
Tom Crockett

20
그래서 사람들은 다른 사람들이 과거에 그 단어를 사용했을 때 의미했던 것과 실질적으로 다른 것을 의미하기 위해 용어를 사용하는 습관을 갖고있는 것 같습니다. 내가 말하는 것 : 영어에 오신 것을 환영합니다.
다니엘 프랫

17
@DanielPratt : 부작용없는 것이 기능 프로그래머가 의미하는 바라면 왜 "참조 투명성"이라고 부릅니까? 그들은 단지 "부작용이없는 것"이라고 부를 수 있는데, 이것은 완전히 명확한 생각입니다. 누구도 스택 부작용에 대해 "부유 효과"의 의미를 묻지 않아도됩니다. 아무도 이해하지 못하는 웅장한 고전 용어를 도용 할 필요성이 어디에 있습니까?
Uday Reddy

23

식은 알고리즘을 변경하지 않고 값으로 대체 할 수있는 경우 참조 적으로 투명하므로 동일한 효과를 가지며 동일한 입력에서 출력되는 알고리즘이 생성됩니다.


18

참조 적으로 투명한 함수는 수학 함수처럼 작동하는 함수입니다. 동일한 입력이 주어지면 항상 동일한 출력을 생성합니다. 전달 된 상태는 수정되지 않으며 함수에는 자체 상태가 없음을 의미합니다.


10

간결한 설명이 필요한 사람들에게는 위험 할 수 있습니다 (그러나 아래의 설명을 읽으십시오).

프로그래밍 언어의 참조 투명성은 방정식 추론을 촉진합니다. 참조 투명성이 클수록 방정식 추론을 수행하는 것이 더 쉽습니다. 예를 들어 (의사) 함수 정의

fx = x + x,

이 축소를 수행 할 수있는 위치에 너무 많은 제약이없이이 정의의 범위에서 f (foo)를 foo + foo로 (안전하게) 대체 할 수있는 편의성은 프로그래밍 언어의 참조 투명도를 나타내는 좋은 지표입니다. 있다.

예를 들어 foo가 C 프로그래밍 의미에서 x ++ 인 경우이 축소를 안전하게 수행 할 수 없습니다 (즉,이 축소를 수행하는 경우 시작한 동일한 프로그램으로 끝나지 않습니다).

실제 프로그래밍 언어에서는 완벽한 참조 투명성을 볼 수는 없지만 기능적 프로그래머는 대부분의 것 이상을 중요하게 생각합니다 (핵심 목표 인 Haskell 참조).

(전체 공개 : 저는 기능 프로그래머이므로 최고 답변 으로이 설명을 소금 한알과 함께 섭취해야합니다.)


3
방정식 추론을 용이하게하는 언어에는 문제가 없습니다. 그러나 나는 그것이 고전적으로 정의 된 "참조 투명성"과 관련이 있다고 주장 할 것이다. 둘째, 실용적인 프로그래머로서 방정식 추론이 과대 평가되었다고 생각합니다. 실제로 중요한 추론은 전제 조건, 사후 조건, 변형 및 데이터 추상화와 관련이 있습니다. 그러한 추론 기법에 의존하는 사람들에게는 부작용이별로 중요하지 않은 것 같습니다. 따라서 표현의 부작용이 나쁜 생각이라는 데 동의하지만 살인자 주장을 나타내는 것으로 보이지는 않습니다.
Uday Reddy

1
@UdayReddy 기능 프로그래머가 프로그램에서 참조 투명성을 다이얼링하는 특정 방법 (부작용을 제거하고 정교하고 강력한 프로그램의 대수를 개발)을 선택했거나 참조 투명성을 이해하지 못하는 실무자가 기능적 프로그래밍 언어가 참조 투명성을 높이 지 못하거나 기능적 언어 프로그래머와 컴파일러 작성자가 공식적인 다루기 성의 증가를 많은 좋은 목적으로 이용하고 있지 않다는 것을 의미하지는 않습니다.
chrisdornan

2
Chris : Uday는 Strachey가 프로그래밍 언어 의미 체계, 특히 명령형 언어 의 참조 불투명도 문제를 제거했다고 지적했습니다 . 따라서 기능 프로그래머는 "프로그램에서 참조 투명도를 다이얼링"할 수 없습니다. 구체적인 예로, Haskell IO는 RT 도움말이 필요 없으므로 RT에 대한 도움말이 아닙니다.
Conal

2
@ chrisdornan : 위의 첫 번째 의견에 대해 죄송합니다. 나는 처음 두 문장에서 내가 말하고자하는 것을 만드는 데 어려움을 겪었다 .- (그러나 여기에 설명이있다. 2 단계 또는 다단계 스테이징 미적분을 고려하자. 그러나 인용 연산자이지만, 각 단계 내에서 방정식 추론을 완벽하게 수행 할 수 있으므로, 참조 적으로 불투명 한 각 연산자는 방정식 추론에 대한 경계를 설정하지만 여전히 그 경계 내에 방정식 추론이 있습니다.
Uday Reddy

1
@ chrisdomain : 또한, 그러한 준비 운영자를 추방하기 위해 참조 투명성 순수 주의자가 되고자하는 사람은 거의 없습니다. 이 연산자는 매우 유용합니다. 수동으로 스테이징을 수행하지 않고 프로그래밍하면 번거롭고 오류가 발생하기 쉽고 추악합니다. 그리고 수동으로 스테이징을 수행한다고해서 이전의 것보다 더 많은 방정식 추론을 구매할 수는 없습니다. 따라서 방정식 추론을 추구하는 데 좋은 프로그래밍 장치를 금지하는 것은 코를 잘라 얼굴을 자극하는 것과 같습니다.
Uday Reddy

8

어원에 관심이있는 경우 (즉,이 개념에 이러한 특정 이름이있는 이유) 해당 주제에 대한 내 블로그 게시물 을 살펴보십시오 . 이 용어는 철학자 / 논리학자인 Quine에서 유래했습니다.


4
  1. Denstional-semantics는 대표 가치 를 구성하는 도메인을 구축하여 모델링 언어를 기반으로 합니다 .
  2. 함수형 프로그래머는 이라는 용어를 사용 하여 언어의 다시 쓰기 규칙에 따라 계산의 수렴을 설명합니다. 운영 의미론.

1에는 문제가되는 두 가지 언어가 명확합니다.

  • 모델링되는 것, 객체 언어
  • 모델링 언어, 메타 언어

2에서는 물체와 금속 언어의 근접성 덕분에 혼란 스러울 수 있습니다.

언어 구현 자로서 나는이 차이점을 끊임없이 기억해야한다는 것을 알게되었습니다.

그래서 Reddy 교수는 당신을 다음과 같이 말로 표현할 수 있습니다 :-)

함수형 프로그래밍 및 의미의 맥락에서 참조 투명성 이라는 용어 는 참조 용으로 투명하지 않습니다.


1
ㅋ. 설명 주셔서 감사합니다. 문제는 기능 프로그래머가 마치 모든 프로그래밍 언어에 적용 할 수있는 "참조 투명성"이라는 일반적인 개념을 갖고있는 것처럼 행동한다는 것입니다 . 그러나 이것은 "가치"라는 개념에 의존하며, 이는 다른 언어에는 적합하지 않을 수도 있습니다. "참조 투명성"에 대한 일반적인 이론을 주장하려면 일반적인 이론 "값"을 만들어야합니다. 그것은 지금까지 누락되었습니다.
Uday Reddy 2012 년

4

다음 희망적인 답변은 논쟁의 여지가있는 1 차 및 3 차 답변을 추가하고 자격을 부여합니다.

표현이 일부 지시자를 나타내거나 언급한다는 것을 인정합시다. 그러나 질문은 이러한 참조를 표현 자체를 '값'이라고 부르는 표현 자체의 일부로 동형으로 인코딩 할 수 있는지 여부입니다. 예를 들어, 리터럴 숫자 값은 산술 표현식 세트의 서브 세트이고, 진리 값은 부울 표현식 세트의 서브 세트입니다. 아이디어는 표현식을 해당 값 (있는 경우)으로 평가하는 것입니다. 따라서 '값'이라는 단어는 표기법 또는 식 집합의 고유 요소를 나타낼 수 있습니다. 그러나 만약 지시자와 가치 사이에 동 형사상 (bijection)이 있다면 그것들은 같은 것이라고 말할 수 있습니다. (이는 언급 적 의미론 분야에서 입증 된 바와 같이 지시자와 동 형사상을 정의하는 데 신중해야한다고 언급했다.data Nat = Zero | Suc Nat 자연수 집합에 예상대로 일치하지 않습니다.)

E[·]구멍이있는 표현식을 작성해 보자 . 일부 분기에서 '컨텍스트'라고도한다. C 유사 표현식에 대한 두 가지 컨텍스트 예제는 [·]+1[·]++입니다.

[[·]]어떤 의미를 제공하는 우주에서 표현 (홀 없음)을 취하고 그 의미 (참조, 표시 등)를 전달하는 함수를 작성해 봅시다 . (나는 의미 적 의미론 분야에서 표기법을 빌리고 있습니다.)

우리가 다소 공식적으로 Quine의 정의를 적용하자로 다음과 문맥이 E[·] 두 표현 주어진 referentially 투명 IFF이다 E1하고 E2(아무 구멍이) 같은 그 [[E1]] = [[E2]](표현이 나타내는 예 / 참조 - 동일한 지시 대상) 다음 그 경우는 [[E[E1]]] = [[E[E2]]](즉, 충전 - E1또는 구멍이있는 구멍 E2에서 동일한 참조를 나타내는 표현식이 표시됨).

등호를 대체하는 Leibniz의 규칙은 일반적으로 'if E1 = E2then E[E1] = E[E2]' 으로 표시되며 이는 E[·]함수입니다. 함수 (또는 함수를 계산하는 프로그램의 경우)는 소스에서 타겟으로의 매핑이므로 각 소스 요소마다 최대 하나의 대상 요소가 있습니다. 결정적이지 않은 함수는 오명자이며, 관계, 집합을 전달하는 함수 등입니다. 만약 Leibniz의 규칙에서 평등 =이 치명적이라면 이중 대괄호는 당연한 것으로 간주되고 생략됩니다. 따라서 투명한 문맥은 함수입니다. 그리고 라이프니츠의 규칙은 방정식 추론의 주요 성분이므로, 방정식 추론은 참조 투명성과 관련이 있습니다.

[[·]]표현식에서 표시까지의 함수 이지만 표현식의 제한된 하위 집합으로 이해되는 표현식에서 '값'까지의 함수일 [[·]]수 있으며 평가로 이해 될 수 있습니다.

이제 E1표현이고 E2가치 인 경우 표현, 가치 및 평가 측면에서 참조 투명성을 정의 할 때 대부분의 사람들이 의미하는 것으로 생각합니다. 그러나이 페이지의 첫 번째 및 세 번째 답변에서 알 수 있듯이 이것은 부정확 한 정의입니다.

와 같은 문맥의 문제 [·]++는 부작용이 아니지만 그 값이 C에서 그 의미와 동형으로 정의되지 않는다는 것입니다. 함수는 값이 아니며 (글쎄, 함수에 대한 포인터는) 함수형 프로그래밍 언어에서는 그 자체입니다. 랜딘 (Landin), 스트라 키 (Strachey), 그리고 의미 론적 의미론의 개척자들은 기능적 세계를 사용하여 의미를 제공하는 데 상당히 영리했습니다.

명령형 C와 유사한 언어의 경우 함수를 사용하여 표현식에 의미를 제공 할 수 있습니다 [[·]] : Expression -> (State -> State x Value).

Value의 하위 집합입니다 Expression. State쌍 (식별자, 값)을 포함합니다. 시맨틱 함수는 표현식을 취하여 현재 상태에서 업데이트 된 상태 및 값을 가진 쌍으로 함수를 의미로 전달합니다. 예를 들어, [[x]]현재 상태에서 첫 번째 구성 요소가 현재 상태이고 두 번째 구성 요소가 x 값인 쌍까지의 함수입니다. 반대로, [[x++]]현재 상태에서 첫 번째 성분이 x의 값이 증가한 상태이고 두 번째 성분이 바로 그 값인 쌍까지의 함수입니다. 이러한 의미에서, 문맥 [·]++은 위에 주어진 정의를 만족시키는 경우에 참조 적으로 투명하다.

함수 프로그래머는 [[·]]표현에서 값까지 자연스럽게 함수로 복구된다는 점에서 참조 투명성을 사용할 자격이 있다고 생각 합니다. 함수는 일류 값이며 상태는 주석이 아닌 값일 수도 있습니다. 상태 모나드는 상태를 전달하는 (또는 스레딩) 깨끗한 메커니즘입니다.


아마도 "1st"& "3rd"답변은 각각 UdayReddy의 "3 월 25 일"및 "postscript"답변입니다. 서수는 SO에서 답을 참조하는 좋은 방법이 아닙니다. 투표 및 수락은 시간이 지남에 따라 변경 될 수있을뿐만 아니라 선택 가능한 여러 가지 주문이 있습니다.
philipxy

2

이 "의미"라는 개념은 관찰자의 마음에서 일어나는 것입니다. 따라서 동일한 "참조"는 다른 사람들과 다른 것을 의미 할 수 있습니다. 예를 들어, 우리는 Wikipedia에 에딘버러 명확성 페이지가 있습니다.

프로그래밍의 맥락에서 나타날 수있는 관련 문제는 다형성 일 수 있습니다.

그리고 아마도 우리는 다형성의 특별한 경우에 대한 이름을 가져야합니다. 정수형 또는 복합 형 또는 다양한 다른 유형을 사용하는 경우 다형성으로 처리 할 수 ​​있습니다.


0

할당 작업 을 도입하여 참조 투명도 를 위반 하는 방법에 대한 설명으로 보완되므로 " 컴퓨터 프로그램의 구조 및 구현 "(마법사 책) 책에서 참조 투명도 의 정의가 유용하다는 것을 알았습니다 . 다음 슬라이드 덱을 확인 나는 주제에 대해 만든 : https://www.slideshare.net/pjschwarz/introducing-assignment-invalidates-the-substitution-model-of-evaluation-and-violates-referential-transparency-as- Sicp-the-wizard-book에 대한 설명


0

참조 투명성은 간단히 다음과 같이 표현할 수 있습니다.

  • 어떤 문맥에서도 항상 같은 결과를 평가하는 표현식 [1] ,
  • 동일한 매개 변수가 두 번 주어진 함수는 동일한 결과를 두 번 생성해야합니다 [2] .

예를 들어, 프로그래밍 언어 Haskell은 순수한 기능 언어입니다. 의미 적으로 투명하다는 의미입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.