İşlevsel programlama dilleri neden çöp toplamayı gerektirir?


14

Ghc'nin Haskell'i birleştirici mantık gibi sıralı bir programlama diline çevirmesini ve daha sonra her şey için yığın tahsisini kullanmasını engelleyen nedir? Wikipedia'ya göre, lambda hesabından birleştirici mantığa çeviri önemsizdir ve ayrıca, birleştirici programlama dilleri sadece bellek tahsisi için bir yığına güvenebilir. Bu çeviriyi yapmak ve böylece Haskell ve ocaml gibi diller için çöp toplamayı ortadan kaldırmak mümkün müdür? Bunu yapmanın dezavantajları var mı?

EDIT: buraya taşındı /programming/39440412/why-do-functional-programming-languages-require-garbage-collection


Dil Programlama Kedi bir işlev, yığın tabanlı dilde bir örnek gibi görünüyor.
Petr Pudlák

1
Bu değil çöp toplama (bunun için ihtiyaç yanı sıra) programlama dilleri üzerine lisans derslerinde kaplı olduğu için, bir araştırma düzey bir soru. Lütfen cs.stackexchange.com adresine gidin
Andrej Bauer

Benim hatam. Sorumun cevabını biliyor musunuz?
Nicholas Grasevski

5
Bence bu soruya araştırma düzeyinde yanıt verilecek, çünkü mezun olduğum yıllarda da bununla mücadele ettiğimi hatırlıyorum: Haskell gibi bir dilde her şey yığın üzerinde yaşayan bir işlev uygulaması gibi görünüyor . Kapanışların neden gerekli olduğunu, neden yığın üzerinde yaşadıklarını ve belki de "işlev kapsamından kaçan verilerin" bununla ne ilgisi olduğunu açıklamak çok bilgilendirici bir cevap verecektir (ki bu konuda nitelikli olduğumdan emin değilim, ne yazık ki).
cody

2
λ

Yanıtlar:


16

Aşağıdaki yorumların tümü, işlev değerlerini temsil eden kapaklar ve bir değer bazında değerlendirme sırası kullanan standart bir uygulama stratejisi seçimine dayanmaktadır:

  1. Saf lambda hesabı için çöp toplama gerekli değildir. Bunun nedeni, öbekte döngü oluşturmanın mümkün olmamasıdır: yeni tahsis edilen her değer yalnızca önceden tahsis edilen değerlere referanslar içerebilir ve bu nedenle bellek grafiği bir DAG oluşturur - bu nedenle referans sayımı belleği yönetmek için yeterlidir.

  2. Uygulamaların çoğunda iki nedenden dolayı referans sayımı kullanılmaz.

    1. Bir tür işaretçi tipini (örn., refML'deki tip yapıcısı) desteklerler ve böylece yığındaki gerçek döngüler oluşturulabilir.
    2. Referans sayımı çöp toplama işleminden çok daha az verimlidir,
      • referans sayılarını korumak için çok fazla ek alan gerektirir ve
      • sayıların güncellenmesi genellikle boşa harcanır ve
      • sayım güncellemeleri, paralel performansı öldüren bir sürü yazma çekişmesi yaratır.
  3. Doğrusal olarak yazılan diller referans sayısını ortadan kaldırabilir (esasen sayımlar 0-1 olduğu için: değerin tek bir referansı vardır veya ölüdür ve serbest bırakılabilir).

  4. Ancak yığın tahsisi hala yeterli değildir. Bunun nedeni, serbest değişkenlere atıfta bulunan işlev değerlerinin (yani, işlev kapanışlarını uygulamamız gerekir) oluşturulması mümkündür, eğer yığın üzerinde bir şeyler ayırırsanız, canlı değerler ölü değerlerle araya sokulabilir ve bu yanlış asimptotik neden olur alan kullanımı.

  5. Bir yığını "spagetti yığını" ile değiştirerek doğru asimptotik elde edebilirsiniz (yani yığını yığınta bağlı bir liste olarak uygulayın, böylece ölü çerçeveleri gerektiği gibi kesebilirsiniz).

  6. Gerçek bir yığın disiplini istiyorsanız, "sıralı mantık" temelli yazım sistemlerini kullanabilirsiniz (esasen doğrusal türler eksi değiş tokuş).


2
(2) 'nin - gözlemlenebilir yan etkiler olmasa bile - uygulamaların (karşılıklı) özyineleme için etkili bir operatör olmasını istemesi, yani aslında yığınta bir döngü oluşturan bir neden değil midir?
Andreas Rossberg

@andreasrossberg: Bundan bahsetmeyi düşündüm, ancak özyineleme için y birleştiricisini kullanabileceğiniz için bunu bıraktım.
Neel Krishnaswami
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.