เหตุใดภาษาการเขียนโปรแกรมที่ใช้งานได้จำเป็นต้องมีการรวบรวมขยะ


14

อะไรคือการหยุด ghc จากการแปล Haskell ไปเป็นภาษาการเขียนโปรแกรมที่ต่อกันเช่นตรรกะเชิงการรวมกันแล้วใช้การจัดสรรสแต็คสำหรับทุกสิ่ง ตามที่วิกิพีเดียการแปลจากแลมบ์ดาแคลคูลัสเป็นตรรกะเชิงตรรกะนั้นมีความสำคัญและภาษาการเขียนโปรแกรมที่ต่อกันสามารถพึ่งพากองซ้อนสำหรับการจัดสรรหน่วยความจำเพียงอย่างเดียว เป็นไปได้ไหมที่จะทำการแปลและกำจัดการเก็บขยะสำหรับภาษาเช่น Haskell และ ocaml มีข้อเสียในการทำเช่นนี้?

แก้ไข: ย้ายมาที่นี่/programming/39440412/why-do-functional-programming-languages-require-garbage-collection


แมว Programming Languageลักษณะเช่นตัวอย่างของฟังก์ชันภาษากองเบส
Petr Pudlák

1
นี่ไม่ใช่คำถามระดับการวิจัยเนื่องจากมีการรวบรวมขยะในหลักสูตรระดับปริญญาตรีในภาษาโปรแกรม (เช่นเดียวกับความต้องการ) โปรดย้ายไปที่ cs.stackexchange.com
Andrej Bauer

ความผิดพลาดของฉัน. คุณรู้คำตอบสำหรับคำถามของฉันหรือไม่
Nicholas Grasevski

5
ฉันคิดว่ามีการตอบคำถามในระดับการวิจัยที่จะตอบคำถามนี้เพราะฉันจำได้ว่าต้องดิ้นรนกับมันในช่วงปีที่จบการศึกษาของฉันด้วย: ทุกอย่างในภาษาเช่น Haskell ดูเหมือนว่าเป็นแอปพลิเคชั่นที่ใช้งานอยู่ ฉันคิดว่าการอธิบายว่าเหตุใดการปิดจึงมีความจำเป็นทำไมพวกเขาจึงอาศัยอยู่บนกองและบางทีสิ่งที่ "ข้อมูลที่หนีขอบเขตฟังก์ชั่น" เกี่ยวข้องกับมันจะทำให้ได้คำตอบที่ให้ข้อมูลอย่างมาก (ซึ่งฉันไม่แน่ใจว่า น่าเสียดาย).
ดี้

2
λ

คำตอบ:


16

ความคิดเห็นต่อไปนี้ทั้งหมดได้รับการกำหนดให้เป็นทางเลือกของกลยุทธ์การใช้งานมาตรฐานโดยใช้การปิดเพื่อแสดงค่าของฟังก์ชั่นและลำดับการประเมินผลการโทรตามค่า:

  1. สำหรับแคลคูลัสแลมบ์ดาบริสุทธิ์การเก็บขยะไม่จำเป็น นี่เป็นเพราะมันเป็นไปไม่ได้ที่จะสร้างวงจรในฮีป: ค่าที่จัดสรรใหม่ทั้งหมดสามารถมีการอ้างอิงไปยังค่าที่จัดสรรไว้ก่อนหน้านี้เท่านั้นและกราฟหน่วยความจำจะเป็น DAG - ดังนั้นการอ้างอิงเพียงพอต่อการนับหน่วยความจำ

  2. การใช้งานส่วนใหญ่ไม่ใช้การนับการอ้างอิงด้วยเหตุผลสองประการ

    1. พวกเขาสนับสนุนรูปแบบของตัวชี้ประเภท (เช่นตัวrefสร้างประเภทใน ML) และรอบที่แท้จริงในกองสามารถเกิดขึ้นได้
    2. การนับการอ้างอิงมีประสิทธิภาพน้อยกว่าการเก็บขยะเนื่องจาก
      • ต้องการพื้นที่เพิ่มเติมจำนวนมากเพื่อให้การนับการอ้างอิงและ
      • การอัปเดตการนับมักจะทำให้งานเสียเปล่าและ
      • การอัพเดตจำนวนนับสร้างการโต้แย้งการเขียนจำนวนมากซึ่งฆ่าประสิทธิภาพการทำงานแบบขนาน
  3. ภาษาที่พิมพ์เชิงเส้นสามารถกำจัดจำนวนการอ้างอิงได้ (เป็นหลักเนื่องจากการนับเป็น 0-1: ค่ามีการอ้างอิงเดียวหรือมันจะตายและสามารถเป็นอิสระได้)

  4. อย่างไรก็ตามการจัดสรรสแต็กยังคงไม่เพียงพอ นี่เป็นเพราะมันเป็นไปได้ที่จะสร้างรูปแบบค่าฟังก์ชั่นซึ่งอ้างถึงตัวแปรอิสระ (เช่นเราจำเป็นต้องใช้ฟังก์ชั่นการปิด) ถ้าคุณจัดสรรสิ่งต่าง ๆ บนสแต็คแล้วค่าสดสามารถ interleaved ด้วยค่าตายและสิ่งนี้จะทำให้ การใช้พื้นที่

  5. คุณสามารถรับ asymptotics ที่ถูกต้องได้โดยแทนที่ stack ด้วย "spaghetti stack" (เช่นใช้ stack เป็นรายการที่เชื่อมโยงใน heap เพื่อให้คุณสามารถตัดเฟรมที่ตายแล้วได้ตามต้องการ)

  6. ถ้าคุณต้องการวินัยสแต็กจริงคุณสามารถใช้ระบบประเภทตาม "ตรรกะที่สั่ง" (โดยพื้นฐานแล้วชนิดเชิงเส้นลบด้วยการแลกเปลี่ยน)


2
ไม่ใช่เหตุผลพื้นฐานเพิ่มเติมสำหรับ (2) - แม้ว่าจะไม่มีผลข้างเคียงที่สังเกตได้ - การใช้งานต้องการให้มีการดำเนินการที่มีประสิทธิภาพสำหรับการเรียกซ้ำ (ซึ่งกันและกัน) เช่นหนึ่งที่เกิดวงจรในกองจริงหรือไม่
Andreas Rossberg

@ andreasrossberg: ฉันคิดว่าจะพูดถึงเรื่องนี้ แต่ทิ้งไว้เพราะคุณสามารถใช้ y combinator สำหรับการเรียกซ้ำ
Neel Krishnaswami
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.