함수형 프로그래밍 언어에 가비지 수집이 필요한 이유는 무엇입니까?


14

ghc가 Haskell을 결합 논리와 같은 연결 프로그래밍 언어로 번역 한 다음 모든 것에 대해 스택 할당을 사용하는 것을 막는 이유는 무엇입니까? Wikipedia에 따르면 람다 미적분에서 조합 논리로의 변환은 사소한 일이며 연결 프로그래밍 언어는 메모리 할당을 위해 스택에만 의존 할 수 있습니다. 이 번역을 수행 할 수있어 Haskell 및 ocaml과 같은 언어의 가비지 콜렉션을 제거 할 수 있습니까? 이 작업을 수행하는 데 단점이 있습니까?

편집 : 여기로 이동 /programming/39440412/why-do-functional-programming-languages-require-garbage-collection


언어 프로그래밍 고양이 함수 스택 기반 언어의 예처럼 보인다.
Petr Pudlák

1
가비지 수집은 프로그래밍 언어에 대한 학부 과정 (필요한 것)에서 다루어지기 때문에 연구 수준의 질문 은 아닙니다 . cs.stackexchange.com까지 이동하십시오
안드레이 바우어에게

내 실수. 내 질문에 대한 답을 알고 있습니까?
Nicholas Grasevski

5
학년도에 어려움을 겪고 있음을 기억 하면서이 질문에 대한 연구 수준의 응답이 있다고 생각합니다. 하스켈 과 같은 언어의 모든 기능은 스택에있는 함수 응용 프로그램 처럼 보입니다 . 클로저가 필요한 이유, 이들이 왜 힙에 있는지, 그리고 "함수 범위를 벗어나는 데이터"와 관련이있는 것은 매우 유익한 답변이 될 것입니다. 운수 나쁘게).
cody

2
λ

답변:


16

다음 주석은 함수 값과 값별 평가 순서를 나타내는 클로저를 사용하는 표준 구현 전략의 선택에 전제됩니다.

  1. 순수한 람다 미적분의 경우 가비지 수집이 필요하지 않습니다. 힙에주기를 형성 할 수 없기 때문입니다. 새로 할당 된 모든 값에는 이전에 할당 된 값에 대한 참조 만 포함될 수 있으므로 메모리 그래프는 DAG를 형성하므로 참조 카운트는 메모리를 관리하기에 충분합니다.

  2. 대부분의 구현은 두 가지 이유로 참조 카운팅을 사용하지 않습니다.

    1. 포인터 형식의 형식 (예 : refML 의 형식 생성자)을 지원하므로 힙의 실제주기가 형성 될 수 있습니다.
    2. 참조 카운트는 가비지 수집보다 훨씬 덜 효율적입니다.
      • 참조 횟수를 유지하려면 많은 추가 공간이 필요합니다.
      • 카운트 업데이트는 일반적으로 낭비되는 작업이며
      • 카운트가 업데이트되면 쓰기 성능이 저하되어 병렬 성능이 저하됩니다.
  3. 선형 형식의 언어는 참조 카운트를 제거 할 수 있습니다 (실제로 카운트가 0-1이므로 값에 단일 참조가 있거나 값이 없어지고 해제 될 수 있음).

  4. 그러나 스택 할당으로는 여전히 충분하지 않습니다. 이는 자유 변수를 참조하는 함수 값을 형성 할 수 있기 때문에 (즉, 함수 클로저를 구현해야 함) 스택에 항목을 할당하면 실제 값이 죽은 값으로 인터리브 될 수 있으며 이로 인해 잘못된 점근이 발생할 수 있습니다. 공간 사용량.

  5. 스택을 "스파게티 스택"으로 교체하여 올바른 무증상을 얻을 수 있습니다 (즉, 스택을 힙에 링크 된 목록으로 구현하여 필요에 따라 죽은 프레임을 잘라낼 수 있음).

  6. 실제 스택 규칙을 원하면 "순서화 된 논리"(실제로 선형 유형 빼기 교환)를 기반으로 유형 시스템을 사용할 수 있습니다.


2
(2)가 관찰 가능한 부작용이 없어도 구현에 (상호 적) 재귀에 대한 효율적인 연산자, 즉 실제로 힙에 사이클을 형성하는 효율적인 연산자를 원하는 이유가 아닌가?
Andreas Rossberg

@ andreasrossberg : 언급에 대해 생각했지만 y 결합기를 재귀에 사용할 수 있으므로 생략했습니다.
Neel Krishnaswami
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.