불변성 또는 가변성은 함수형 프로그래밍에서 의미가있는 개념이 아닙니다.
계산 문맥
이것은 다른 최근 질문에 대한 흥미로운 후속 조치 (중복이 아님) 인 매우 좋은 질문입니다. 과제, 평가 및 이름 바인딩의 차이점은 무엇입니까?
나는 당신의 진술에 하나씩 대답하는 대신, 당신에게 위기에 처한 것에 대한 구조적 개요를 제공하려고 노력하고 있습니다.
다음과 같은 몇 가지 문제에 대한 답변이 있습니다.
함수형 프로그래밍 스타일은 명령형 프로그래머의 눈으로 볼 수 있기 때문에 어리석은 것처럼 보입니다. 그러나 그것은 다른 패러다임이며, 당신의 명령 개념과 인식은 외계인입니다. 컴파일러에는 그러한 편견이 없습니다.
그러나 최종 결론은 기계 학습을 포함하여 순수하게 기능적인 방식으로 프로그램을 작성할 수 있다는 것입니다. 기능적 프로그래밍에는 데이터 저장 개념이 없다고 생각했습니다. 나는이 시점에서 다른 답변에 동의하지 않는 것 같습니다.
희망적 으로이 답변의 길이에도 불구하고 소수의 사람들이 관심을 가질 것입니다.
계산 패러다임
문제는 이론적이며 가장 간단한 대표가 람다 미적분학 인 특정 계산 모델 인 기능적 프로그래밍 (일명 응용 프로그래밍)에 관한 것입니다.
이론적 인 수준에 머무르면 튜링 머신 (TM), RAM 머신 및 기타 머신 , 람다 미적분, 조합 논리, 재귀 함수 이론, 반 색조 시스템 등 많은 계산 모델이 있습니다. 모델은 그들이 다룰 수있는 것의 측면에서 동등한 것으로 입증되었으며, 이것이 교회 튜링 논문 의 요지입니다
.
중요한 개념은 모델을 서로 축소하는 것인데, 이것은 교회-튜링 논문으로 이어지는 동등성을 확립하기위한 기초입니다. 프로그래머의 관점에서 볼 때 한 모델을 다른 모델로 줄이는 것은 보통 컴파일러라고하는 것입니다. 논리 프로그래밍을 계산 모델로 사용하면 상점에서 구입 한 PC에서 제공하는 모델과는 상당히 다르며 컴파일러는 논리 프로그래밍 언어로 작성된 프로그램을 PC가 나타내는 계산 모델로 변환합니다. RAM 컴퓨터).
그러나 두 모델이 동일한 방식으로 작동하거나 특정 개념이 다른 개념으로 이전 될 수 있다는 의미는 아닙니다. 일반적으로 TM의 계산 단계는 (β-) Lambda 미적분의 감소 단계는 서로 번역 가능합니다. 람다 식의 최적 평가 개념은 TM 모델의 복잡성 문제와는 거리가 멀다.
실제로, 우리가 사용하는 프로그래밍 언어는 서로 다른 이론적 기원의 개념을 혼합하는 경향이 있으며,이를 위해 프로그램의 선택된 부분이 적절한 경우 일부 모델의 속성을 활용할 수 있습니다. 마찬가지로, 시스템을 구축하는 사람들은 현재 작업에 가장 적합한 언어로 구성 요소마다 다른 언어를 선택할 수 있습니다.
따라서 프로그래밍 언어에서 순수한 상태의 프로그래밍 패러다임을 보는 경우는 거의 없습니다. 프로그래밍 언어는 여전히 지배적 인 패러다임에 따라 분류되지만, 다른 패러다임의 개념이 관련 될 때 언어의 속성에 영향을 줄 수 있으며, 종종 구별과 개념적 문제를 흐리게합니다.
일반적으로 Haskell 및 ML 또는 CAML과 같은 언어는 기능적인 것으로 간주되지만 명령형 동작을 허용 할 수 있습니다. 그렇지 않으면 왜 " 순전히 기능적인 하위 집합 "에 대해 이야기 합니까?
그런 다음 기능 프로그래밍 언어 로이 작업을 수행 할 수 있다고 주장 할 수는 있지만 추가 기능으로 간주 될 수있는 것에 의존 할 때 기능 프로그래밍에 대한 질문에 실제로 대답하지는 않습니다.
답변은 추가 사항없이 특정 패러다임과 더 정확하게 관련되어야합니다.
변수 란 무엇입니까?
또 다른 문제는 용어 사용입니다. 수학에서 변수는 일부 도메인에서 결정되지 않은 값을 나타내는 엔티티입니다. 다양한 목적으로 사용됩니다. 방정식에서 사용되면 방정식이 확인되도록 모든 값을 나타낼 수 있습니다. 이 비전은 아마도 논리 프로그래밍이 개발 될 때 이름 변수가 이미 다른 의미를 가지고 있었기 때문에 " 논리 변수 "라는 이름으로 논리 프로그래밍에 사용됩니다.
전통적인 명령형 프로그래밍에서 변수는 값의 표현을 기억하고 현재 값을 다른 것으로 대체 할 수있는 일종의 컨테이너 (또는 메모리 위치)로 이해됩니다.
함수형 프로그래밍에서 변수는 어떤 가치를위한 자리 표시 자와 같이 수학에서 사용하는 것과 같은 목적을 갖지만 아직 제공되지는 않습니다. 전통적인 명령형 프로그래밍에서이 역할은 실제로 상수에 의해 수행됩니다 ( 123, true, [ "abdcz", 3.14]와 같은 값의 도메인에 고유 한 표기법으로 표현 된 값으로 결정된 리터럴 과 혼동되지 않아야 함 ).
상수뿐만 아니라 모든 종류의 변수는 식별자로 나타낼 수 있습니다.
명령형 변수는 값을 변경할 수 있으며 이는 가변성의 기초입니다. 기능 변수는 불가능합니다.
프로그래밍 언어는 일반적으로 언어의 작은 개체에서 더 큰 개체를 만들 수 있도록합니다.
명령형 언어를 사용하면 이러한 구문에 변수를 포함시킬 수 있으며 이는 가변 데이터를 제공하는 것입니다.
프로그램을 읽는 방법
프로그램은 기본적으로 알고리즘에 대한 추상적 인 설명입니다. 실용적인 디자인이든 패러다임 적으로 순수한 언어이든 언어입니다.
원칙적으로 추상적으로 의미하는 바에 대한 모든 진술을 취할 수 있습니다. 그런 다음 컴파일러는이를 컴퓨터가 실행하기에 적합한 형식으로 변환하지만 첫 번째 근사치의 문제는 아닙니다.
물론, 현실은 조금 더 거칠고, 컴파일러가 효율적인 실행을 처리하는 방법을 알지 못하는 구조를 피하기 위해 어떤 일이 발생하는지에 대해 잘 알고있는 것이 좋습니다. 그러나 그것은 이미 최적화입니다 ... 어떤 컴파일러는 프로그래머보다 훨씬 좋을 수 있습니다.
기능적 프로그래밍 및 가변성
변경 가능성은 할당에 의해 변경 될 값을 포함 할 수있는 명령 변수의 존재를 기반으로합니다. 이것들은 함수형 프로그래밍에는 존재하지 않기 때문에 모든 것이 불변으로 보일 수 있습니다.
함수형 프로그래밍은 값만 처리합니다.
불변성에 대한 첫 네 가지 진술은 대부분 정확하지만 명령이 아닌 것을 명령 식으로 묘사하십시오. 그것은 모두가 장님 인 세상에서 색상으로 묘사하는 것과 약간 같습니다. 함수형 프로그래밍에 익숙하지 않은 개념을 사용하고 있습니다.
순수한 값만 있고 정수 배열은 순수한 값입니다. 한 요소에서만 다른 다른 배열을 얻으려면 다른 배열 값을 사용해야합니다. 요소를 변경하는 것은이 맥락에서 존재하지 않는 개념 일뿐입니다. 배열과 일부 색인을 인수로 갖는 함수를 가질 수 있으며, 색인으로 표시된 위치 만 다른 거의 동일한 배열 인 결과를 리턴합니다. 그러나 여전히 독립 배열 값입니다. 이러한 가치가 어떻게 표현 되는가는 문제가 아닙니다. 어쩌면 그들은 컴퓨터의 명령 번역에서 많은 것을 "공유"하지만 컴파일러의 일입니다 ... 그리고 어떤 종류의 기계 아키텍처가 컴파일되고 있는지 알고 싶지 않습니다.
당신은 값을 복사 하지 않습니다 (이치가 없으며 외계인의 개념입니다). 프로그램에서 정의한 도메인에 존재하는 값만 사용하십시오. 리터럴로 설명하거나 다른 값에 함수를 적용한 결과입니다. 프로그램의 다른 위치에서 동일한 값이 사용되도록 이름을 지정하여 상수를 정의 할 수 있습니다. 함수 어플리케이션은 계산이 아니라 주어진 인수에 대한 어플리케이션의 결과로 인식되어야합니다. 쓰기 5+2
또는 쓰기 7
같은 금액을. 이전 단락과 일치합니다.
명령형 변수가 없습니다. 할당이 불가능합니다. 지정 가능한 변수에 이름을 바인딩 할 수있는 명령형 언어와 달리 이름 만 값에 바인딩하여 상수를 형성 할 수 있습니다.
복잡한 비용이 있는지는 확실하지 않습니다. 우선, 복잡성 우려 명령형 패러다임에 대해 언급합니다. 기능적 프로그램을 명령형 프로그램으로 읽도록 선택하지 않는 한, 기능적 프로그래밍에 대해서는 그렇게 정의되지 않습니다. 이는 디자이너의 의도가 아닙니다. 실제로 기능적 관점은 이러한 문제에 대해 걱정하지 않고 계산 대상에 집중할 수 있도록하기위한 것입니다. 그것은 사양과 구현과 약간 비슷합니다.
컴파일러는 구현에주의를 기울여야하며, 수행 할 하드웨어에 무엇을해야하는지에 대해 가장 잘 적응할 수있을 정도로 똑똑해야합니다.
나는 프로그래머가 그것에 대해 걱정하지 않는다고 말하는 것이 아닙니다. 또한 프로그래밍 언어와 컴파일러 기술이 원하는만큼 성숙하다고 말하는 것은 아닙니다.
질문에 대답
기존 값 (외계인 개념)은 수정하지 않지만 원하는 경우 다른 요소를 하나 추가하여 목록에있는 새 값을 계산하십시오.
프로그램은 새로운 데이터를 얻을 수 있습니다. 요점은 언어로 표현하는 방법입니다. 예를 들어, 프로그램이 크기 제한이없는 하나의 특정 값 (입력 스트림이라고 함)으로 작동한다고 생각할 수 있습니다. 그것은 거기에 앉아 있어야 할 가치입니다 (이미 완전히 알려 졌는지 아닌지 당신의 문제가 아닌지). 그런 다음 스트림의 첫 번째 요소와 나머지 스트림으로 구성된 쌍을 반환하는 함수가 있습니다.
이를 사용하여 순전히 적용 방식으로 통신 구성 요소의 네트워크를 구축 할 수 있습니다 (코 루틴)
머신 러닝은 데이터를 정확하게 작성하고 값을 수정해야 할 때 또 다른 문제입니다. 함수형 프로그래밍에서는 그렇게하지 않습니다. 훈련 데이터에 따라 적절히 다른 새 값만 계산하면됩니다. 결과 기계도 작동합니다. 걱정하는 것은 컴퓨팅 시간과 공간 효율성입니다. 그러나 다시 말하지만 이는 컴파일러가 이상적으로 처리해야하는 다른 문제입니다.
최종 비고
의견이나 다른 답변에서 실용적인 함수형 프로그래밍 언어는 순전히 기능하지 않습니다. 이는 특히 컴파일과 관련하여 기술이 여전히 개선되어야한다는 사실을 반영한 것입니다.
순전히 적용 가능한 스타일로 글을 쓸 수 있습니까? 그 대답은 약 40 년 동안 알려져 왔으며 "예"입니다. 1970 년대에 등장한 denatotional semantics의 목적은 언어를 순전히 기능적인 스타일로 정확하게 번역 (컴파일)하고 수학적으로 더 잘 이해하는 것으로 간주되어 프로그램의 의미를 정의하기위한 더 나은 자금으로 간주되었습니다.
흥미로운 점은 변수를 포함한 명령형 프로그래밍 구조가 데이터 저장소와 같은 적절한 값의 도메인을 도입함으로써 기능적 스타일로 변환 될 수 있다는 것입니다. 그리고 기능적 스타일에도 불구하고, 명령형 스타일로 작성된 실제 컴파일러의 코드와 놀랍게도 유사합니다.