함수형 프로그래밍에서 영구 데이터 구조를 사용하는 이유는 무엇입니까?


22

함수형 프로그래밍은 영구적 인 데이터 구조와 불변 개체를 사용합니다. 내 질문은 여기에 그러한 데이터 구조를 갖는 것이 왜 중요합니까? 데이터 구조가 영구적이지 않으면 어떻게 될지 저수준 으로 이해하고 싶습니다 . 프로그램이 더 자주 충돌합니까?


답변:


19

변경 불가능한 데이터 객체로 작업 할 때 함수는 동일한 입력으로 호출 할 때마다 동일한 출력을 생성하는 속성을 갖습니다. 이를 통해 계산을보다 쉽게 ​​개념화하고 올바르게 처리 할 수 ​​있습니다. 또한 테스트하기가 더 쉽습니다.

그것은 시작에 불과합니다. 수학은 오랫동안 함수와 함께 일해 왔기 때문에 수학에서 빌려서 프로그램에 대한 엄격한 추론에 사용할 수있는 많은 추론 기법이 있습니다. 필자의 관점에서 가장 중요한 장점은 기능적 프로그램을위한 타입 시스템이 잘 개발되었다는 것입니다. 따라서 어딘가에 실수를하면 유형 불일치로 나타날 가능성이 매우 높습니다. 따라서 형식화 된 기능 프로그램은 명령형 프로그램보다 훨씬 더 안정적인 경향이 있습니다.

반대로 변경 가능한 데이터 개체로 작업 할 때는 먼저 계산 중에 개체가 수행하는 여러 상태를 기억하고 관리하는 인지력이 있습니다. 특정 단계에 필요한 모든 속성이 해당 시점에 충족되도록 올바른 순서로 작업을 수행해야합니다. 실수하기가 쉽고, 타입 시스템은 그러한 실수를 잡기에 충분하지 않습니다.

수학은 변경 가능한 데이터 객체와 함께 작동하지 않았습니다. 따라서 우리가 그들로부터 빌릴 수있는 추론 기법은 없습니다. 컴퓨터 과학, 특히 Floyd-Hoare Logic 에서 개발 한 자체 기술이 많이 있습니다 . 그러나 이것들은 표준 수학 기술보다 마스터하기가 더 어렵고, 대부분의 학생들은 그 기술을 다룰 수 없으므로 거의 배우지 않습니다.

두 패러다임의 차이점에 대한 간략한 개요를 보려면 프로그래밍 언어 원칙에 대한 강의 노트의 처음 몇 가지 유인물을 참조하십시오 .


이것은 나에게 많은 의미가 있습니다. PPT를 공유해 주셔서 감사합니다. 당신은 같은 비디오 녹화를 공유합니까?
gpuguy

@gpuguy. 나는 그다지 파워 포인트를 사용하지 않습니다. 화이트 보드는 내가 가장 좋아하는 매체입니다. 그러나 유인물은 스스로 읽을 수 있어야합니다.
Uday Reddy

+1 수학은 변경 가능한 데이터 객체와 함께 작동하지 않았습니다. 또한 강의 노트 링크.
Guy Coder

15

변경 가능한 데이터 구조로 작업하는 것보다 지속적 데이터 구조로 올바르게 작업하는 것이 더 쉽습니다 . 이것이 주요 장점이라고 생각합니다.

물론 이론적으로 말해서, 우리가 영구적 인 데이터 구조로 할 수있는 것은 변경 가능한 구조로 할 수도 있고 그 반대도 가능합니다. 대부분의 경우 persitent 데이터 구조는 추가 비용을 발생시킵니다. 대개 일부는 복사해야하기 때문입니다. 이러한 고려 사항은 30 년 전 슈퍼 컴퓨터의 메모리가 휴대 전화보다 적은 메모리를 사용했을 때 영구적 인 데이터 구조를 훨씬 덜 매력적으로 만들었을 것입니다. 그러나 오늘날 소프트웨어 생산의 주요 병목 현상은 개발 시간과 유지 관리 비용으로 보입니다. 따라서 우리는 개발 효율성을 위해 실행 효율성을 기꺼이 희생 할 것입니다.

지속적인 데이터 구조를 사용하는 것이 더 쉬운 이유는 무엇입니까? 인간은 프로그램의 다른 부분들 사이 에서 앨리어싱 과 다른 종류의 예기치 않은 상호 작용 을 추적하는 데 정말로 나쁘기 때문 입니다. 그들은 자동으로 두 가지를 호출하기 때문에 생각 x하고 y, 다음 commmon에 아무것도 없다. "아침 별"과 "저녁 별"이 실제로 같은 것을 알아 내려면 노력해야합니다. 마찬가지로 데이터 구조가 다른 스레드와 함께 작동하거나 데이터 구조를 변경하는 방법 등을 호출했기 때문에 데이터 구조가 변경 될 수 있다는 사실을 잊어 버리기가 매우 쉽습니다. 지속적인 데이터 구조.

영구 데이터 구조에는 다른 기술적 이점도 있습니다. 일반적으로 최적화하는 것이 더 쉽습니다. 예를 들어, 원하는 경우 항상 영구 데이터 구조를 클라우드의 다른 노드에 자유롭게 복사 할 수 있습니다. 동기화에 대한 걱정은 없습니다.


그것이 많은 장점을 가질 때 왜 명령형 언어로 영구적 인 데이터 구조를 사용하지 않습니까?
gpuguy 2013

4
아마도 당신은 "왜 명령형 언어를 사용 하는가?"라고 물을 것입니다.
Andrej Bauer

4
그러나 진지하게, 영구적 인 구조로 대체하기 어려운 데이터 구조가 있습니다. 예를 들어, 배열과 행렬을 사용하는 숫자 처리 프로그램은 전통적인 데이터 구조보다 훨씬 빠릅니다.
Andrej Bauer

1
@gpuguy. 영구적 인 데이터 구조는 적용 가능하고 적합한 경우 항상 명령형 언어로 사용될 수 있으며 사용해야합니다. 이를 사용하려면 언어가 가비지 콜렉션 기반 메모리 관리를 지원해야합니다. 많은 현대 언어에는 Java, C #, Scala, Python, Ruby, Javascript 등이 있습니다.
Uday Reddy

논란의 여지가 있지만, 하나의 큰 장점은 변경 가능한 데이터 구조와 비교하여 더 추상적 인 인터페이스입니다. 후드 아래에서 항목을 변경할 수 있지만 (참조 불변성 대 참조 무결성) 그렇지 않아도됩니다.
Raphael

2

함수형 프로그래밍은 다른 사람의 답변에 추가하고 수학적 접근 방식을 강화하여 Relational Algebra 및 Galois Connections와의 시너지 효과가 있습니다.

이것은 공식적인 방법 영역에서 매우 유용합니다.
예를 들어 :

  • 프로그램 검증의 공식적인 증거는 Extended Static Checking으로 단순화됩니다.
  • Relational Algebra의 여러 속성은 Alloy와 같은 도구를 사용하여 SAT 해석에 유용합니다.
  • Galois Connections는 이 블로그 에서 볼 수 있듯이 Shin-Cheng Mu와 José Nuno Oliveira 의 논문을 참조 하여 소프트웨어 사양에 대한 계산 접근 방식을 허용합니다 .
  • Galois Connections (및 기능적 프로그래밍)는 Hoare Logic보다 일반적인 개념이므로 계약 방식으로 Design 방식으로 사용할 수 있습니다.

{}{}[]ϕϕ[]

  • []
  • ϕϕ)

이 접근 방식은 또한 가장 약한 전제 조건가장 강한 후 조건 계산을 허용하여 여러 상황에서 유용합니다.


2

데이터 구조가 영구적이지 않으면 어떻게 될지 저수준으로 이해하고 싶습니다.

데이터 구조로 거대한 상태 공간 (예 : 2450 바이트의 " 메르 센 트위스터 ")을 가진 의사 난수 생성기를 살펴 보자 . 우리는 임의의 숫자를 두 번 이상 사용하고 싶지 않으므로이를 불변의 영구 데이터 구조로 구현할 이유가 거의없는 것 같습니다. 이제 다음 코드에서 무엇이 잘못 될지 스스로 물어 보자.

mt_gen = CreateMersenneTwisterPRNGen(seed)
integral = MonteCarloIntegral_Bulk(mt_gen) + MonteCarloIntegral_Boundary(mt_gen)

대부분의 프로그래밍 언어는 순서 지정하지 않은 MonteCarloIntegral_BulkMonteCarloIntegral_Boundary평가됩니다. 둘 다 가변 mt_gen을 인수로 참조하는 경우이 계산의 결과는 플랫폼에 따라 다를 수 있습니다. 더 나쁜 것은, 다른 실행 사이에 결과를 전혀 재현 할 수없는 플랫폼이있을 수 있습니다.

하나는 임의의 실행 인터리빙되도록 mt_gen위한 효율적인 가변 데이터 구조를 설계 할 수 MonteCarloIntegral_BulkMonteCarloIntegral_Boundary"정확한"결과를 제공하지만, 다른 "올바른"결과 일반적인 리드의 다른 인터리빙된다. 이 재현 불가능 성은 대응하는 기능을 "불완전하게"만들고, 다른 문제를 야기한다.

고정 된 순차적 실행 순서를 시행함으로써 재현 불가능 성을 피할 수있다. 그러나이 경우 코드는 주어진 시간에 mt_gen에 대한 단일 참조 만 사용할 수 있도록 배열 될 수 있습니다. 형식화 된 기능적 프로그래밍 언어에서는 고유성 형식을 사용하여이 제약 조건을 적용 할 수 있으므로 순수한 기능적 프로그래밍 언어의 맥락에서도 안전한 변경 가능한 업데이트가 가능합니다. 이 모든 것이 멋지고 멋지게 들릴지 모르지만 적어도 이론 상으로는 Monte Carlo 시뮬레이션은 당황 스럽습니다.우리의 "솔루션"은이 속성을 파괴했습니다. 이것은 단지 이론적 인 문제가 아니라 매우 실제적인 문제입니다. 그러나 우리는 의사 난수 생성기와 생성하는 난수 시퀀스를 수정해야하며, 프로그래밍 언어로는 자동으로이를 수행 할 수 없습니다. (물론 우리는 이미 필요한 기능을 제공하는 다른 의사 난수 라이브러리를 사용할 수 있습니다.)

낮은 레벨에서, 가변적 인 데이터 구조는 실행 순서가 순차적이고 고정적이지 않은 경우, 재현 불가능 (불순물)을 쉽게 초래할 수있다. 이러한 문제를 해결하기위한 일반적인 명령 전략은 수정 가능한 데이터 구조가 변경되는 고정 실행 순서의 순차적 단계와 모든 공유 가능한 변경 가능한 데이터 구조가 일정하게 유지되는 임의의 실행 순서의 병렬 단계를 갖는 것입니다.


Andrej Bauer는 변경 가능한 데이터 구조에 대한 앨리어싱 문제를 제기했습니다. 흥미롭게도 Fortran 및 C와 같은 다른 명령형 언어는 함수 인수의 허용 앨리어싱에 대한 다른 가정을 가지고 있으며 대부분의 프로그래머는 해당 언어에 앨리어싱 모델이 있다는 것을 잘 알지 못합니다.

불변성과 가치 의미가 약간 과대 평가 될 수 있습니다. 더 중요한 것은 프로그래밍 언어의 유형 시스템과 논리적 프레임 워크 (예 : 추상 기계 모델, 앨리어싱 모델, 동시성 모델 또는 메모리 관리 모델)가 "효율적인"데이터로 "안전하게"작업 할 수 있도록 충분한 지원을 제공한다는 것입니다 구조. C ++ 11에 "이동 의미론"을 도입하는 것은 이론적 관점에서 순도 및 "안전성"측면에서 거대 단계로 거슬러 올라갈 수 있지만 실제로는 반대입니다. 새로운 의미 체계와 관련된 위험의 상당 부분을 제거하기 위해 언어의 유형 시스템과 논리 프레임 워크가 확장되었습니다. (가장자리가 거칠더라도 이것이 "더 나은"것으로 개선 될 수 없다는 것을 의미하지는 않습니다


Uday Reddy는 수학이 변경 가능한 데이터 객체와 함께 작동하지 않았으며 기능 프로그램의 유형 시스템이 변경 불가능한 데이터 객체를 위해 잘 개발되었다는 문제를 제기했습니다. 이것은 선형 논리에 동기를 부여하려고 할 때 수학이 변하기 쉬운 객체를 다루는 데 사용되지 않는다는 Jean-Yves Girard의 설명을 떠올리게했습니다.

"효율적인"가변 비 영구 데이터 구조로 "안전하게"작업 할 수 있도록 함수형 프로그래밍 언어의 형식 시스템 및 논리적 프레임 워크를 확장하는 방법을 묻습니다. 여기서 하나의 문제는 고전 논리와 부울 대수가 가변 데이터 구조를 다루는 데 가장 적합한 논리 프레임 워크가 아닐 수도 있다는 것입니다. 아마도 선형 논리 와 전산 적 monoid가 그 작업에 더 적합할까요? 아마도 필립와 들러 (Fhilip Wadler)가 함수형 프로그래밍 언어를위한 타입 시스템으로서 선형 로직에 대해 무엇 을 말해야 하는지 읽어보아야 합니까? 그러나 선형 로직이이 문제를 해결할 수 없어도 기능적 프로그래밍 언어의 타입 시스템과 논리적 프레임 워크를 "안전하고"효율적으로 확장 할 수 없다는 의미는 아닙니다.


@DW 당신은 ​​아마이 답변이 독립형 답변이 아니라는 것이 맞을 것입니다. 그것은 현재 Uday Reddy와 Andrej Bauer의 답변에서 제기 된 특정 포인트에서만 확장됩니다. 독립형으로 수정하고 "데이터 구조가 영구적이지 않은 경우 어떻게 될지 낮은 수준에서 이해하고 싶습니까?" 질문의 일부. 데이터 구조로 거대한 상태 공간 (예 : 2450 바이트 상태의 "Mersenne twister")을 가진 의사 난수 생성기를보고 잘못 될 수있는 사항을 설명합니다.
Thomas Klimpel

@DW 나는이 질문에 대한 답이 실제로 그 질문에 대답한다고 생각하지 않습니다. 특히, 영구 데이터 구조가 실제로 무엇인지 (불변이 아닌 것) 그리고 어떻게 구현되는지에 대해서는 아무 것도 없습니다.
Guildenstern
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.