Ana Sayfa

Nix'te Yığın Taşmasını genericClosure ile Aşmak

1 dk okuma

Nix, saf, tembel ve döngüsüz bir dil olduğu için tüm tekrarlamalar özyineleme (recursion) yoluyla yapılır ve bu da yığın çerçeveleri (stack frames) tüketir. Nix 2.20'den itibaren, değerlendirici (evaluator) çağrı derinliğini varsayılan olarak 10.000 ile sınırlamaktadır. Bu limit, lib.splitString gibi yaygın fonksiyonlarda veya derin NixOS konfigürasyonlarında kolayca aşılabilirken, bir yorumlayıcı veya doğrulayıcı gibi girdi boyutuna orantılı hesaplama yapan sistemlerde anında bir engel teşkil eder. Mevcut C++ değerlendiricisi kuyruk çağrısı optimizasyonunu (TCO) desteklemediği için bu durum, geliştiriciler için önemli bir sorun yaratmaktadır.

Makale, bu yığın taşması sorununu, tamamen farklı bir amaç için tasarlanmış olan builtins.genericClosure yerleşik fonksiyonunu kullanarak O(1) çağrı yığını derinliği ile nasıl aşılabileceğini gösteriyor. genericClosure, bir iş listesi algoritması (worklist algorithm) uygulayarak çalışır. Başlangıç düğümleri kümesi ve her düğümü alıp yeni keşfedilecek düğümleri döndüren bir operatör fonksiyonu alır. Daha önce ziyaret edilen düğümler atlanır ve sonuç, keşif sırasına göre tüm ziyaret edilen düğümlerin bir listesidir.

Bu fonksiyonun dahili uygulaması, özyineleme içermeyen bir C++ while döngüsüne dayanır, bu da yığın büyümesini engeller. genericClosure, başlangıçta paket bağımlılık kapanımlarını hesaplamak için tasarlanmıştır ve nixpkgs'ta lib.closePropagation'ın yerini aldığında değerlendirme hızını 15.5 kat artırmıştır. Bu teknik, Nix'teki derin hesaplamaların yığın taşması olmadan verimli bir şekilde yürütülmesini sağlayarak, dilin yeteneklerini genişletmektedir.

İçgörü

Bu çözüm, Nix kullanıcılarının karmaşık ve derin hesaplamaları yığın taşması endişesi olmadan gerçekleştirmelerine olanak tanıyarak Nix dilinin pratik kullanım alanlarını genişletiyor.

Kaynak