범위의 끝에 스택 의미론 (자동 결정 론적 파괴)을 사용할 수있는 기능적 언어가 있습니까?
범위의 끝에 스택 의미론 (자동 결정 론적 파괴)을 사용할 수있는 기능적 언어가 있습니까?
답변:
함수형 프로그래밍 전문가는 아니지만 내가 아는 것은 없습니다.
함수에서 반환 된 값에는 동일한 함수 내에서 생성 된 (스택에서) 다른 값에 대한 참조가 포함되거나 매개 변수로 쉽게 전달되거나 전달 된 무언가에 의해 참조 될 수 있기 때문에 원칙적으로 매우 어려운 것 같습니다. 매개 변수로. C 에서이 문제는 프로그래머가 올바르게 작동하지 않으면 매달려있는 포인터 (또는 더 정확하게는 정의되지 않은 동작)가 발생할 수 있도록하여 처리됩니다. 기능적 언어 디자이너가 승인하는 솔루션이 아닙니다.
그러나 잠재적 인 해결책이 있습니다. 한 가지 아이디어는 값의 수명을 값에 대한 참조와 함께 값 유형의 일부로 만들고 스택 할당 값이 반환되거나 무언가에서 참조되는 것을 방지하는 유형 기반 규칙을 정의하는 것입니다. 기능. 나는 그 의미를 극복하지 못했지만 그것이 끔찍한 것으로 생각됩니다.
모나 딕 코드의 경우 (실제로 또는 거의) 모나 딕이며 자동으로 결정적으로 파괴되는 IORef를 제공 할 수있는 또 다른 솔루션이 있습니다. 원칙은 "중첩"동작을 정의하는 것입니다. 결합 연산자를 사용하여 결합하면 중첩 제어 흐름을 정의합니다. "XML 요소"라고 생각합니다. 가장 왼쪽의 값은 바깥 시작 태그와 끝 태그 쌍을 제공합니다. 이 "XML 태그"는 다른 추상화 레벨에서 모나 딕 동작의 순서를 정의합니다.
어떤 시점에서 (연관 구성 체인의 오른쪽에) 중첩을 끝내려면 중간에 구멍을 채우는 일종의 터미네이터가 필요합니다. 터미네이터가 필요하다는 것은 아마도 네스트 컴포지션 연산자가 모나 딕하지 않다는 것을 의미하지만, 세부 사항을 다루지 않았으므로 완전히 확실하지 않습니다. 터미네이터를 적용하면 중첩 동작을 효과적으로 구성된 일반 모나 딕 동작으로 변환 할 수 있습니다. 반드시 중첩 컴포지션 연산자에 영향을 미치지는 않습니다.
이러한 특수 조치 중 많은 부분이 널 "종료 태그"단계를 가지며 "시작 태그"단계를 간단한 monadic 조치와 동일시합니다. 그러나 일부는 변수 선언을 나타냅니다. 이것들은 begin-tag를 가진 생성자와 end-tag를 가진 소멸자를 나타냅니다. 그래서 당신은 같은 것을 얻습니다 ...
act = terminate ((def-var "hello" ) >>>= \h ->
(def-var " world") >>>= \w ->
(use-val ((get h) ++ (get w)))
)
다음과 같은 실행 순서로 모나 딕 구성으로 변환하면 각 태그 (요소가 아님)는 정상적인 모나 딕 동작이됩니다.
<def-var val="hello"> -- construction
<def-var val=" world> -- construction
<use-val ...>
<terminator/>
</use-val> -- do nothing
</def-val> -- destruction
</def-val> -- destruction
이와 같은 규칙을 사용하면 C ++ 스타일 RAII를 구현할 수 있습니다. 일반 IORef가 모나드를 이스케이프 할 수없는 이유와 유사한 이유로 IORef와 같은 참조는 범위를 벗어날 수 없습니다. 연관 구성 규칙은 참조를 이스케이프 할 방법을 제공하지 않습니다.
편집 -나는 거의 말을 잊어 버렸습니다-여기에 확실하지 않은 명확한 영역이 있습니다. 외부 변수가 내부 변수를 참조 할 수 없도록하는 것이 중요하므로 기본적으로 이러한 IORef와 같은 참조로 수행 할 수있는 작업에 제한이 있어야합니다. 다시, 나는 모든 세부 사항을 다루지 않았습니다.
따라서 구성은 예를 들어 파괴가 닫히는 파일을 열 수 있습니다. 건축은 소켓이 열리고 파괴가 닫힙니다. 기본적으로 C ++에서와 같이 변수는 자원 관리자가됩니다. 그러나 C ++과 달리 자동으로 파괴 할 수없는 힙 할당 객체는 없습니다.
이 구조는 RAII를 지원하지만 가비지 수집기가 여전히 필요합니다. 중첩 작업이 메모리를 할당하고 해제하여 리소스로 취급 할 수는 있지만 해당 메모리 덩어리 및 다른 곳에 기능적 값에 대한 모든 참조가 여전히 존재합니다. 메모리가 스택에 간단하게 할당 될 수 있고 힙이 필요없는 것을 피할 수 있다면 다른 종류의 리소스 관리에있어 중요한 의미가 있습니다.
따라서 이것이 달성하는 것은 RAII가 단순한 중첩 범위를 기반으로하는 경우 RAII 스타일 자원 관리를 메모리 관리와 분리하는 것입니다. 메모리 관리를 위해 가비지 수집기가 여전히 필요하지만 다른 리소스를 안전하고시기 적절하게 자동으로 정리할 수 있습니다.
shared_ptr<>
여전히 결정 론적 파괴를 유지합니다. RAII에 까다로운 것은 순환 참조입니다. 소유권 그래프가 방향 비순환 그래프 인 경우 RAII가 제대로 작동합니다.
C ++을 함수형 언어 (람다가 있음)로 간주하면 가비지 수집을 사용하지 않는 언어의 예입니다.
나는 "기능적 언어"의 표준 모음이 있다고 가정하기 때문에 질문이 잘못 정의되었다고 말해야한다. 거의 모든 프로그래밍 언어는 어느 정도의 기능적 프로그래밍을 지원합니다. 그리고 거의 모든 프로그래밍 언어는 일정량의 명령형 프로그래밍을 지원합니다. 문화적 편견과 대중적인 교리에 의해 인도되는 것 외에, 기능적 언어와 명령형 언어 중 어느 것을 말할 수 있는가?
문제를 표현하는 더 좋은 방법은 "스택 할당 메모리에서 기능적 프로그래밍을 지원하는 것"입니다. 이미 언급했듯이 대답은 매우 어렵습니다. 함수형 프로그래밍 스타일은 필요에 따라 재귀 데이터 구조의 할당을 촉진합니다. 여기에는 힙 메모리 (가비지 수집 또는 참조 횟수)가 필요합니다. 그러나 영역 기반 메모리 분석 이라고하는 매우 정교한 컴파일러 분석 기술이 있습니다.이를 사용하면 스택 할당과 유사한 방식으로 힙을 큰 블록으로 분할하여 자동으로 할당 및 할당 해제 할 수 있습니다. Wikipedia 페이지에는 "기능적"및 "제 국적"언어에 대한 다양한 기술 구현이 나열되어 있습니다.