1 puan yazan GN⁺ 2 시간 전 | 1 yorum | WhatsApp'ta paylaş
  • Yaklaşık 3 yıl önce bayt kodu VM ve çöp toplayıcıyı Zig ve unsafe Rust ile bizzat yazdığımda Zig'in insan dostu ergonomisi öndeydi; ancak kodlama ajanları çağına girilmesiyle bu üstünlük fiilen anlamsız hale geldi
  • Zig'in sunduğu temel özelliklerin sağladığı 1,5 ila 5 kat geliştirici üretkenliği artışı, Rust tabanlı kodlama ajanlarının sunduğu 100 kat üretkenlik artışı karşısında eziliyor
  • Zig'in allocator arayüzü, keyfi bit genişliğinde tamsayılar, packed struct, comptime gibi çekirdek özelliklerinin tamamı, insanların kodu doğrudan yazdığı durumlarda parlayan özellikler
  • Rust'ın tip sistemi, bounded polymorphism ve invariant zorlaması sayesinde ajanların hatalarını derleme zamanında önlemede daha etkili
  • Ajanların ürettiği kod miktarının 100 kat arttığı bir ortamda Rust'ın bellek güvenliği garantisi, Zig'e kıyasla belirleyici bir avantaj

Temel değişim

  • Zig, unsafe kod ergonomisi açısından büyük bir avantaja sahipti; ancak insanların doğrudan kod yazma oranı azalınca bu avantajın pratikteki değeri de küçüldü
  • Zig özelliklerinin sağladığı 1,5 ila 5 kat düzeyindeki insan geliştirici üretkenliği artışı, Rust'ta kodlama ajanları kullanmanın sağladığı 100 kat artışın gölgesinde kalıyor
  • Zig'in öne çıkan birçok özelliği insanların elle kod yazarkenki rahatlığını artırıyor, ancak kodlama ajanları için bu fark çok önemli değil
  • Yaklaşık 3 yıl önce Zig ve unsafe Rust ile bir bayt kodu VM ve çöp toplayıcı yazarken, unsafe kod yazma deneyiminin Zig tarafında daha iyi olduğunu düşünmüştüm
  • 2026 itibarıyla Zig hâlâ iyi bir dil, ancak Rust'ın daha çok tercih edildiği ve kodlama ajanlarıyla da daha iyi uyum sağlayan dil haline geldi

Zig'in allocator arayüzü

  • Zig'in allocator arayüzü, belirli kod yollarını optimize etmek için arena, stack fallback gibi özel allocator'ların kolayca uygulanmasını sağlıyor
  • Kullanıcı girdisinden tek satır okuma durumunda giriş uzunluğu teorik olarak sınırsız olduğu için heap allocator gerekir; ancak pratikte girişlerin çoğu kısa arama sorguları veya yollar olduğundan 1KB'den çok daha küçüktür
  • std.heap.stackFallback(256, heap_allocator), sabit boyutlu bir tamponu stack üzerinde tutup yalnızca girdi taşarsa heap'e geçerek tipik durumda heap allocation olmadan işlem yapılmasını sağlar
  • Geçmişte Rust'ta Zig'in Allocator arayüzüne denk gelen bir özellik yoktu; bu yüzden custom allocator kullanan bir Vec<T> gerekiyorsa standart kütüphane uygulamasını kopyalayıp değiştirmeniz gerekirdi
  • Bumpalo'nun koleksiyon kaynak kodu, standart koleksiyonların fork edilip bump allocator'a bağlanmış haliydi
  • Rust nightly'de bir süredir Allocator trait'i vardı ve şimdi yeterince iyi görünen bir düzeye gelmiş durumda
  • Rust'taki Allocator trait tabanlı olduğu için statik dispatch kullanır; Zig'in allocator'ları ise vtable tabanlıdır
  • Zig'deki gibi veri yapılarını allocator parametresine göre tasarlayan topluluk genelindeki bir gelenek Rust'ta yok; ancak yapay zekanın kodu kopyalayıp değiştirmesi kolaylaştıkça bu sınırlama daha az önemli hale geliyor

Keyfi bit genişliğinde tamsayılar ve packed struct

  • Zig'in keyfi bit genişliğinde tamsayıları ve packed struct, veri odaklı tasarım tarzı CPU önbellek optimizasyonu, tagged pointer, NaN boxing ve bitflags gibi işleri kolaylaştırıyor
  • Obj-C API'sini Metal ile birlikte Objective-C runtime C API üzerinden kullanırken id, hizalanmış bir heap nesnesi işaretçisi değil, bir tagged pointer olabilir
  • Hizalamayı varsayan koda tagged NSNumber verilirse UB oluşabilir; bu yüzden bunun “heap pointer mı yoksa tagged immediate mı” olduğunu ucuza kontrol etmek gerekir
  • Basitleştirilmiş bir Objective-C tagged pointer yerleşiminde en düşük 1 bit “heap pointer değil” anlamına gelir, sonraki 3 bit sınıf yuvasını tanımlar ve kalan 60 bit payload olur
  • Zig, enum(u3) ve packed struct ile class: TaggedClass, payload: u60 gibi bit yerleşimini doğrudan tip olarak ifade etmeye olanak tanır
  • Zig'de @bitCast ile ham u64 ve ObjcTaggedPointer arasında geçiş yapılabilir; is_ns_number içinde de is_tagged ve .ns_number sınıfı kontrol edilebilir
  • Rust karşılığındaki kod, ObjcTaggedPointer(u64) içinde TAG_MASK, CLASS_MASK, CLASS_SHIFT, PAYLOAD_SHIFT gibi sabitler tanımlar; oluştururken OR işlemleri yapar ve erişimde maskeler uygular
  • Rust'ta sınıf yuvası gerçek bir tip değil u64 sabitidir; bunu elle yazmak Zig'e göre daha az ergonomiktir
  • Rust'ta bitfield veya bitflags gibi crate'ler kullanmak daha iyi olabilir; ancak ikisi de proc macro'lara dayanır ve Zig'in packed struct'u kadar iyi hissettirmez
  • Kodlama ajanları olduğunda bu tür kodları elle yazmanın zahmeti büyük ölçüde azalır

comptime'ın değişen değeri

  • Zig'in comptime özelliği en gösterişli yeteneklerinden biri; bazı zor anlaşılan bağımlı tip dilleri hariç, Zig kadar iyi derleme zamanı değerlendirmesi sunan dil neredeyse yok denebilir
  • Gerçek kullanımda comptime'ı artık çok özlemez oldum; kullanımın yaklaşık %95'i parametrik tipli generic veri yapıları oluşturmak içindi
  • fn ArrayList(comptime T: type) type gibi, tipi alıp items: []T, capacity: usize, allocator: Allocator alanlarına sahip bir struct tipi döndüren kalıp bunun tipik örneğidir
  • Rust'ın tip sistemi, Zig tarzı comptime generics'in önemli bir kısmının yerini alabiliyor ve daha fazla invariant'ı zorlayabiliyor
  • Kalan yaklaşık %5'lik durumda comptime olmaması rahatsız edici ve güvenilir tek alternatif codegen
  • Oyun geliştirmede araçların ürettiği hitbox geometry verisini sabit kod olarak veri yapısına koymak istediğinizde, Rust'ta Claude'a Rust dosyası üreten bir script yazdırmanız gerekir
  • Buna rağmen derleme zamanı değerlendirmesine pratikte çok sık ihtiyaç duyulmuyor

Rust tip sisteminin avantajları

  • Rust'ın tip sistemi, Zig'in comptime'ına göre daha değerli bir takas olarak görülüyor; özellikle bounded polymorphism için traits/typeclasses alanında güçlü
  • Zig'de aynı düzeyde bounded polymorphism gerçekleştirmeye çalışmak çok zor
  • Rust'ın tip sistemi daha fazla invariant zorlayabiliyor; bu da kodlama ajanlarının sık yaptığı hataları önlemeye yardımcı oluyor
  • Oyun kodunda euclid crate'i, grafik programlamada yaygın bir sorun olan koordinat uzaylarının karıştırılmasını önlemek için kullanılıyor
  • Point<Screen> veya Point<World> gibi her koordinat uzayına özel tipler oluşturursanız, dünya koordinatları ile ekran koordinatlarının yanlışlıkla karıştırılması derleme aşamasında engellenir
  • WorldPoint, WorldVector, ScreenPoint gibi ayrı tipler tanımlandığında aynı uzaydaki point ve vector toplaması yapılabilir
  • Translation2D::<f32, WorldSpace, ScreenSpace> ile dünya uzayından ekran uzayına açıkça dönüşüm yapılabilir
  • Buna karşılık let bad: ScreenPoint = player; gibi WorldPoint'i doğrudan ScreenPoint'e atayan kod kabul edilmez

Bellek sorunlarıyla daha az uğraşmanın etkisi

  • Kodlama ajanları 100 kat daha fazla kod yazmayı mümkün kılıyorsa, Zig kodunda bellek sorunları açısından incelenmesi gereken miktar da 100 kat artar
  • Biçimsel doğrulama yoksa, hataları bulmak için bakmanız gereken arama alanının yüzey alanı çok daha büyür
  • Bugünkü gibi üretilen kod miktarının arttığı bir ortamda Rust daha çekici hale geliyor
  • Rust'ın geleneksel ödünleşimi, borrow checker'a alışık değilseniz geliştirici üretkenliğini düşürmesiydi; ancak kodlama ajanları varken bu dezavantaj çok daha az önemli hale geliyor
  • Rust'ta unsafe kullansanız bile miri gibi araçları kodlama ajanına çalıştırarak UB oluşup oluşmadığını ve Rust'ın aliasing kurallarının ihlal edilip edilmediğini kontrol edebilirsiniz

Sonuç

  • Zig hâlâ özlenen ve iyi bir dil
  • 2026'nın çalışma tarzında Rust daha çok tercih ediliyor ve kodlama ajanlarıyla uyumu da daha iyi

1 yorum

 
GN⁺ 2 시간 전
Lobste.rs görüşleri
  • Eski ekip liderim, kopyala-yapıştır kodun her zaman kötü olmadığına dair oldukça güçlü bir görüşe sahipti
    DRY ilkesi yüzünden içgüdüsel olarak yanlış ya da tartışmalı geliyordu, ama kendisi çok pragmatik biriydi ve bu ilkeyi çoğunlukla büyük test kod tabanlarına uyguluyordu
    Mantığı şuydu: zekice ortak arayüzleri zorla üretmeye çalışmak yerine, basit ama daha büyük ve daha tekrarlı bir kod tabanı bakım açısından daha kolay olabilir
    Bugünlerde LLM kullanırken yine aynı düşünceye dönüyorum; artık bunu yazılımın daha önemli kısımlarına da uyguluyorum
    Kod üretimi hızlı ve LLM'ler de basit ama tekrarı bol kod tabanlarında daha iyi isabet ediyor gibi görünüyor

    • Özellikle testlerde tamamen WET, yani “yazarak çözelim” tarafındayım
      Tekrarı azaltmak için testlere fazla soyutlama koyarsanız, testleri anlamak zorlaşır ve ince hatalara açık hale gelir
      Daha da kötüsü, test edilen kodun soyutlamasını yeniden kullanırsanız test de aynı şekilde yanlış olabilir
      Ayrıca uygulama kodundan farklı olarak testler fiilen bedavaya “birleştirilir”
      Test harness'ını ciddi biçimde bozmadıysanız, testleri istediğiniz gibi ekleyip çıkarabilirsiniz; bu diğer testleri etkilemez ve entegrasyon sürtünmesi de olmadığı için tekrardan kaçınmak için bir neden daha ortadan kalkar
    • Katılıyorum
      Testlerde bunun DAMP diye ifade edildiğini görmüştüm: “Descriptive and Meaningful Phrases”, yani özgünlükten çok okunabilirliği öne çıkaran bir ilke
      Bu ilke benzer kodların tekrarı gibi bir yinelenme yaratabilir, ama testlerin açıkça doğru görünmesini sağlar
      https://testing.googleblog.com/2019/12/…
      Go topluluğunda da benzer bir söz var: “küçük bir kopya, küçük bir bağımlılıktan iyidir” https://go-proverbs.github.io/
    • Repeat yourself, do more than one thing, and rewrite everything yazısını ilk okuduğumda gerçekten çok etkilenmiştim
    • İçgüdüsel olarak yanlış geliyordu kısmına gelirsek, aslında baştan beri hiç yanlış değildi
    • Andrew Kelley'nin kod yazışını izlerken iyi bir ders çıkardım
      Canlı kodlama yayınlarını paylaştığı için minnettarım
      Yanlış hatırlamıyorsam, bir şeye başlarken sık sık yapmak istediğine en çok benzeyen kodu bulup tamamını kopyalıyor, sonra onun üzerinden değiştiriyordu
      “İkisinin paylaştığı soyutlamanın ne olduğunu düşünmek için oturup zaman harcamıyor musun?” diye düşünmüştüm, ama o sadece kopyala-yapıştır yaparak ilerliyordu ve benden çok daha üretkendi
  • Bun'ın Zig → Rust AI yeniden yazımı düşünüldüğünde zamanlaması ilginç https://xcancel.com/jarredsumner/status/2053063524826620129#m

    • Bun'a yakın zamanda birleştirilen 150 PR'dan 108'i bellek güvenliğiyle ilgiliydi; hata yollarında temizliğin atlanması, use-after-free, başlatılmamış okuma, sınır dışı erişim ve yeniden giriş gibi sorunlardı
      Bunların 75'inin, yıkıcılar, taşıma semantiği ve borrow checker olan bir dilde derlenmeyeceği söyleniyor
      Yani dağıtıma çıkan her üç PR'dan biri “hata yolunda serbest bırakmayı unuttuk” düzeyinde
      108'in yaklaşık 88'inin Zig tarafında olduğu, C++ tarafındaki yaklaşık 14'ün ise çoğunlukla referans döngüleri ve GC eşzamanlılık yarışları gibi hangi dil olursa olsun kalan artık kategoriler olduğu söyleniyor
      Dolayısıyla Zig→Rust farkı gerçek; Zig hataları tam da yıkıcılar ve sahiplik ile düzeltilebilecek türden ve C++ tarafı zaten tabana yakın
      Daha güçlü derleme zamanı güvenceleri olmadan bu iş kedi-fare oyunu olarak kalmaya devam edecek
      Öneri, en büyük hata kategorisini tek tek düzeltmeye devam etmek yerine yapısal olarak ortadan kaldırmak
      bun/docs/rust-rewrite-plan.md at claude/phase-a-port · oven-sh/bun · GitHub
  • “Kalan %5'lik durumda comptime olmadan eziyet oluyor ve eşdeğer sonuca reliably ulaşmanın tek yolu kod üretimi” kısmında yazarın ne demek istediği net değil
    Çünkü prosedürel makrolar hakkında hiçbir şey söylemiyor

    • Zig'in comptime'ı gerçekten harika, ama Rust'ın makro sistemi de asla küçümsenecek bir şey değil
      Doğru kurmak biraz zahmetli olsa da çok şey yapabiliyor
      Kod üretiminin biraz haksız yere kötü bir üne sahip olduğunu da düşünüyorum
      build.rs betikleriyle epey can sıkıcı sorunu kod üretimiyle çözdüm ve gayet iyi çalışıyor
      Tabii ileride pişman olabilirim
  • Yazının ana argümanı kabaca şöyle görünüyor

    1. Veri yapısına göre allocator özelleştirilen belirli bir durumda, kod kopyala-yapıştır maliyeti zor bir problemdi
    2. Rust'ın bazı tip sistemi özellikleri daha kullanışlı. Ama ilgili örnekte Rust'ın tip tasarımını Zig'e taşıyıp comptime ile API şeklini zorlamasını ajana söylemenin mümkün olmadığına inanmak zor
    3. Bit flag veya SoA gibi özelliklerde kod okunabilirliği önemli değil
    4. Derleme bellek güvenliği hatalarının yokluğunu garanti ediyorsa, “100 kat” daha fazla kod gözden geçirilebilir
      Rust iyi bir dil, ama bu yine de biraz fazla
  • Bir kodlama ajanı reklamı gibi görünüyor

    • Kodlama ajanlarının programlama dili seçimini nasıl etkilediğine dair samimi düşünceler gibi de görünüyor
    • Ya da Zig için bir ters psikoloji reklamı olabilir...
  • Aynı yazarın bağlantı verilen başka bir yazısından: grafik programlamada çok yaygın bir hata koordinat uzaylarını karıştırmaktır ve tip sistemi, hangi koordinat uzaylarının ve dönüşümlerin geçerli olduğunu tiplerle ifade edecek kadar güçlü olabilir
    Aynı şey para birimleri, SI birimleri ile İngiliz ölçü birimlerinde mesafe ve ağırlık, doğrulanmış string'ler ile kullanıcıdan gelen string'ler ve gizli değerler için de söylenebilir
    Ayrıca iyi yönetildiğinde durum tipleriyle imkânsız ya da sound olmayan durumlar engellenebilir
    Ama kişisel olarak Rust'ta en çok istediğim özellik veri yarışlarının tamamen ortadan kalkması
    Yönetilen dillerde de veri yarışı var
    “Git Go kullan” denilen Go'da her şey thread'ler arasında referansla değiştirilebilir; bir de üstüne slice cambazlığı var
    Eskiden tamamen oyuncak dil sayılan, en saf ve güvenli tarafta görülen JavaScript'te bile her await potansiyel bir yarış
    everything-is-an-EventEmitter deseninin kötülüğünü bir kenara bıraksak bile
    Yani evet. Sadece GC olsaydı... 🤫

  • Sanki asıl meseleyi biraz gizliyor
    Kodlama ajanları Python ve JavaScript ile de çok iyi iş çıkarıyor
    Rust'tan daha iyi olup olmadığı öznel bir tartışma, ama yine de birçok iş için o dilleri seçmezdim
    Sorunun Zig'in özelliklerinin sık değişmesi mi, yoksa sadece daha yeni bir dil olduğu için AI eğitim verisinin daha bulanık olması mı olduğunu merak ediyorum

  • Bana göre Zig, Rust'tan yazması daha zor ama okuması daha kolay bir dil
    Yapay zeka çağında yazılan koddan çok okunan kod olduğu için ben Zig tarafını tercih etme eğilimindeyim

  • Şu anda üretilen kod miktarına bakınca Rust'ın daha cazip olduğu söylemi sadece ilk adım
    Bilgisayarlar daha fazla kod yazdıkça, daha biçimsel diller avantaj kazanacak
    Bu, dinamik tip tartışmasının bir sonraki aşaması gibi görünüyor
    “Dinamik tipler insanlar için daha kolayken neden makine için aynı şeyi üç kez belirtelim ki?” gibi
    Tipler, yaşam süreleri... makinelerin yazıp tüketmesini kolaylaştıran başka neler var?
    Gelecekte bilgisayarların kod yazdığı dillerde insanların doğrudan kod yazması ne kadar zorlaşacak, merak ediyorum