Tại sao các ngôn ngữ lập trình chức năng yêu cầu thu gom rác?


14

Điều gì ngăn cản ghc chuyển dịch Haskell sang ngôn ngữ lập trình ghép nối như logic kết hợp và sau đó chỉ đơn giản là sử dụng phân bổ ngăn xếp cho mọi thứ? Theo Wikipedia, việc dịch từ phép tính lambda sang logic kết hợp là không đáng kể, và ngoài ra, các ngôn ngữ lập trình nối có thể chỉ dựa vào một ngăn xếp để cấp phát bộ nhớ. Có khả thi để thực hiện bản dịch này và do đó loại bỏ bộ sưu tập rác cho các ngôn ngữ như Haskell và ocaml không? Có những nhược điểm để làm điều này?

EDIT: đã chuyển đến đây /programming/39440412/why-do-feftal-programming-lacular-require-garbage-collection


Các Cát Lập trình Ngôn ngữ trông giống như một ví dụ về một hàm, ngôn ngữ dựa trên stack.
Petr Pudlák

1
Đây không phải là một câu hỏi cấp độ nghiên cứu, vì bộ sưu tập rác được bao phủ trong các khóa học đại học về ngôn ngữ lập trình (cũng như sự cần thiết của nó). Vui lòng chuyển đến cs.stackexchange.com
Andrej Bauer

Lỗi của tôi. Bạn có biết câu trả lời cho câu hỏi của tôi?
Nicholas Grasevski

5
Tôi nghĩ rằng có một số câu trả lời ở cấp độ nghiên cứu được đưa ra cho câu hỏi này, vì tôi nhớ mình cũng phải vật lộn với nó trong suốt những năm học cấp hai: mọi thứ trong một ngôn ngữ như Haskell trông giống như một ứng dụng chức năng, sống trên chồng. Tôi nghĩ rằng việc giải thích tại sao việc đóng cửa là cần thiết, tại sao họ sống trong đống, và có lẽ "dữ liệu thoát khỏi phạm vi chức năng" phải làm gì với nó sẽ đưa ra một câu trả lời rất nhiều thông tin (mà tôi không chắc là tôi đủ điều kiện để đưa ra, không may).
cody

2
Tôi đồng ý rằng các phần của câu hỏi là cấp độ nghiên cứu. Có các cách tiếp cận khác nhau để quản lý bộ nhớ, ví dụ như dựa trên khu vực (theo Tofte, Talpin), dựa trên loại affine (Rust). Việc dịch -calculus thành tổ hợp dẫn đến một vụ nổ kích thước. λ
Martin Berger

Câu trả lời:


16

Tất cả các ý kiến ​​sau đây là tiền đề cho việc lựa chọn chiến lược thực hiện tiêu chuẩn bằng cách sử dụng các bao đóng để biểu diễn các giá trị hàm và thứ tự đánh giá theo giá trị:

  1. Đối với tính toán lambda thuần túy, việc thu gom rác là không cần thiết. Điều này là do không thể hình thành các chu kỳ trong heap: mọi giá trị được phân bổ mới chỉ có thể chứa các tham chiếu đến các giá trị được phân bổ trước đó và do đó biểu đồ bộ nhớ tạo thành một DAG - do đó, việc đếm tham chiếu đủ để quản lý bộ nhớ.

  2. Hầu hết các triển khai không sử dụng tính tham chiếu vì hai lý do.

    1. Chúng hỗ trợ một dạng kiểu con trỏ (ví dụ: hàm tạo refkiểu trong ML) và do đó các chu kỳ thực trong heap có thể được hình thành.
    2. Việc đếm tham chiếu ít hiệu quả hơn nhiều so với thu gom rác, vì
      • nó đòi hỏi nhiều không gian bổ sung để giữ số lượng tham chiếu và
      • cập nhật số lượng thường là lãng phí công việc, và
      • các bản cập nhật cho tổng số tạo ra một loạt các cuộc tranh luận viết mà giết chết hiệu suất song song.
  3. Các ngôn ngữ được nhập tuyến tính có thể loại bỏ số tham chiếu (về cơ bản vì số đếm là 0-1: hoặc giá trị có một tham chiếu đến nó hoặc nó đã chết và có thể được giải phóng).

  4. Tuy nhiên, phân bổ ngăn xếp vẫn không đủ. Điều này là do có thể hình thành các giá trị hàm tham chiếu đến các biến miễn phí (nghĩa là chúng ta cần thực hiện việc đóng hàm), nếu bạn phân bổ mọi thứ trên ngăn xếp, thì các giá trị sống có thể được xen kẽ với các giá trị chết và điều này sẽ gây ra sự tiệm cận không chính xác sử dụng không gian.

  5. Bạn có thể có được sự tiệm cận đúng bằng cách thay thế một ngăn xếp bằng "ngăn xếp spaghetti" (nghĩa là triển khai ngăn xếp như một danh sách được liên kết trong heap, để bạn có thể cắt bỏ các khung chết nếu cần).

  6. Nếu bạn muốn có một kỷ luật ngăn xếp thực sự, bạn có thể sử dụng các hệ thống loại dựa trên "logic theo thứ tự" (về cơ bản là các loại tuyến tính trừ trao đổi).


2
Không phải là lý do cơ bản hơn cho (2) rằng - ngay cả khi không có tác dụng phụ có thể quan sát được - việc triển khai muốn có một toán tử hiệu quả cho đệ quy (lẫn nhau), tức là, một cái thực sự tạo thành một chu kỳ trong đống?
Andreas Rossberg

@andreasrossberg: Tôi đã nghĩ đến việc đề cập đến điều đó, nhưng hãy bỏ qua vì bạn có thể sử dụng bộ kết hợp y để đệ quy.
Neel Krishnaswami
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.