3 puan yazan GN⁺ 2023-10-26 | 1 yorum | WhatsApp'ta paylaş
  • WebAssembly’ye odaklanmak için JavaScript’ten Rust’a geçtikten sonra 3 yıl boyunca Wick, production dağıtımları, bir ebook ve yaklaşık 100 crates.io paketi geliştirerek Rust’ın gerçek değerini değerlendirdi
  • borrow checker, zengin tip sistemi, fonksiyonel kalıplar ve null yokluğu birçok hatayı derleme aşamasında engelleyerek az testle büyük bir kod tabanını korumayı sağladı
  • Clippy ve Cargo workspace güçlü araçlar, ancak global lint yapılandırması ve workspace dağıtımı gibi araç ve ekosistem boşlukları operasyonel maliyete dönüşüyor
  • async, refactoring ve generic·lifetime·trait constraint yönetimi, JavaScript veya Go’ya kıyasla sürtünmenin daha yüksek olduğu alanlar olmaya devam ediyor
  • Rust sağlam ve çok yönlü, ancak işe alım, öğrenme, hızlı iterasyon ve sorun takibi maliyeti yüksek olduğu için kapsam netse veya başlangıç maliyeti karşılanabiliyorsa daha uygun

WebAssembly, Rust seçimini yönlendirdi

  • Birkaç yıl önce WebAssembly’ye %100 odaklanmak için mevcut işleri bıraktı ve o dönemde Rust, WebAssembly derleme desteği açısından en iyi seçenekti
  • Özellik açısından zengin WebAssembly runtime’ları da Rust tabanlıydı; bu yüzden seçenekler arasında Rust en gerçekçi seçenekti
  • Sonrasında, WebAssembly’yi çekirdek modül sistemi olarak kullanan bir uygulama framework’ü ve runtime’ı olan Wick’i geliştirdi
  • 3 yıl boyunca çeşitli production dağıtımları, ebook ve crates.io’da yaklaşık 100 paket yayımlayarak Rust deneyimi biriktirdi

Az testle daha fazla kodu korumak

  • Rust’ta da diğer dillerdeki gibi test yazarken, aslında sadece derleniyorsa zaten başarısız olamayacak testler yazdığını fark etti
  • unsafe {} blokları ve .unwrap() gibi panic üretmeye yatkın metotlardan kaçınıldığında birçok sorun varsayılan olarak önlenmiş oluyor
  • borrow checker, zengin tip sistemi, fonksiyonel kalıplar ve kütüphaneler ile null değerinin olmaması, test için gereken çabayı azaltıyor
  • Wick projesindeki 70.000 satırdan fazla kodu, başka dillerde ihtiyaç duyulacak olandan çok daha az testle koruyabildi
  • Test gerektiğinde, Rust’ın entegrasyon test harness’i sayesinde bunları kodun hemen yanına kolayca eklemek mümkün

Rust, diğer dillerdeki kodlama alışkanlıklarını da değiştirdi

  • Rust derleyicisi, başka dillerde normal kabul edilen kodlara bile sürekli itiraz ediyor ve bu süreç kodlama alışkanlıklarını değiştiriyor
  • Artık başka dillerde de kod satırlarının sırası tuhafsa veya dönüş değeri kontrol edilmiyorsa rahatsızlık hissediyor
  • Runtime hataları yaşadığında da eskisine göre çok daha güçlü bir hoşnutsuzluk duyuyor
  • Rust’ın katılığı rahatsız edici olsa da, derleyicinin sağladığı korumaya alışınca başka dillere dönmek zorlaşıyor

Clippy, bir lint aracından fazlası olarak faydalı

  • Clippy Rust’ın linter’ı, ancak basit bir denetim aracından çok alternatif kod öneren yardımsever bir yardımcı araca daha yakın
  • Rust standart kütüphanesi çok büyük; çok sayıda tip, trait, macro ve fonksiyona dağılmış özellikler nedeniyle ihtiyaç duyulan API’yi bulmak zor olabiliyor
  • Pek çok kural, standart kütüphane metotları veya tipleriyle daha iyi değiştirilebilecek yaygın kalıpları tespit ediyor
  • Yüzlerce kural performans, okunabilirlik ve gereksiz dolaylılığı ele alıyor; mümkün olduğunda alternatif kod da sunuyor
  • Proje genelinde lint yapılandırması Cargo issue ile mümkün olacak gibi görünüyordu, ancak o zamana kadar Wick onlarca crate içindeki inline lint ayarlarını script ile otomatik güncellemek zorunda kaldı

Ekosistemde katlanılması gereken boşluklar var

  • Global Clippy yapılandırması sorunu, Rust araçları ve kütüphanelerinde sık görülen ekosistem boşluklarının bir örneği
  • İlgili issue’lar bugün kapatılmış olsa da, yıllarca açık kaldılar ve çözülmeleri uzun sürdü
  • Rust uzun süredir “en sevilen dil” seçilerek yeni kullanıcılar çekiyor, ancak bu ivme kütüphane ve araçlarda dramatik iyileşmelere doğrudan dönüşmedi
  • Belirli kullanım senaryolarını ele alan tek seferlik fork’lar sıkça ortaya çıktı; Wick’te de PR göndermeye çalışırken benzer durumlar yaşandı
  • Olası nedenler arasında kararlı API’yi koruma baskısı ve ayrıntılı tip sistemi yer alıyor
    • Kütüphane sahipleri için küçük değişiklikler bile major sürüm değişikliğine yol açabileceğinden bunları kabul etmek zor olabiliyor
    • Herkesin ihtiyaçlarını karşılayan Rust kodu yazmanın yükü de büyük

Cargo, crates.io ve workspace dağıtımındaki sürtünme

  • Wick depo yapısı popüler projeler örnek alınarak tasarlandı ve ilk başta mantıklı görünüyordu, ancak sorunlar dağıtım aşamasında ortaya çıktı
  • Cargo ile modül boyutundaki crate’leri derlemek, test etmek ve kullanmak kolay, ancak crates.io’ya dağıtım ayrı bir mesele
  • crates.io’da, referans verilen tüm crate’lerin paketin yayımlanabilmesi için ayrı ayrı dağıtılmış olması gerekiyor
    • Yalnızca yerel dosya sisteminde bulunan paketlere bağımlı crate’lerin yayımlanmasını engellemesi mantıklı
    • Ancak büyük bir projeyi küçük iç modüllere bölmenin doğal olduğu yapılarda, sadece parent crate içinde bulunan sub-crate’leri içererek yayımlama yapılamıyor
  • Yerel dev dependency içeren crate’lerin de Cargo.toml içinde version yoksa yayımlanabileceğine dair bir düzeltme yapıldı
  • Cargo workspace desteğinin kendisi mükemmel ve büyük projeleri yönetme deneyimi çoğu dilden daha iyi
  • Ancak workspace, dağıtım sorununu çözmüyor; yapılandırma için pek çok seçenek olsa da kolay yayımlanan tek bir “doğru cevap” bulmak zor
  • cargo workspace publish ile ilgili yardımcı crate’lerin çok sayıda olması bile sorunu gösteriyor
  • Wick’i yayımlarken, manuel tekrar eden işleri ve sadece kısmen çalışan araçları birleştirmek yüzünden bunun 1 saatten uzun sürdüğü sık oldu

async en büyük sürtünme kaynaklarından biri

  • Rust’taki async, sanki dil ilk oluşturulduktan sonra eklenmiş bir özellik gibi hissettiriyor ve pratik kullanımda da sonradan eklenmiş gibi sık sık sorun çıkarıyor
  • Hataları anlamak ve çözmek zor; çözüm ararken de çeşitli runtime’lar ve onların async yaklaşımlarına göre elemek gerekiyor
  • Bazı async kütüphanelerinin belirli bir async runtime dışında kullanılamaması mümkün
  • 20 yıllık JavaScript geçmişi ve Go deneyimiyle bakıldığında, Rust async en büyük hayal kırıklığı ve sürtünme kaynağı oldu
  • Aşılamayacak bir sorun değil, ancak async kaynaklı problemlerin her an ortaya çıkabileceğine hep hazırlıklı olmak gerekiyor
  • Diğer dillerde async neredeyse görünmeyecek kadar doğal çalışıyor

Refactoring yorucu bir işe dönüşebiliyor

  • Rust’ın zengin tip sistemi hem avantaj hem dezavantaj
  • Rust tipleriyle düşünmek güzel, ama Rust tiplerini yönetmek bir kabusa dönüşebiliyor
  • Veri ve fonksiyon imzalarında generic type, generic lifetime ve trait constraint bulunabiliyor
  • Constraint’lerin kendileri de tekrar generic type ve lifetime içerebildiğinden, gerçek koddan daha fazla tip constraint bulunan durumlar olabiliyor
  • Her impl için generic’lerin ayrı ayrı tanımlanması gerektiğinden ilk yazımda da zahmetli; refactoring sırasında ise küçük bir değişiklik zincirleme düzeltmelere dönüşebiliyor
  • Aynı constraint veya generic listelerini birçok yerde tekrar etmek gerektiğinde, bunları alias’layacak ya da merkezi tanımdan referanslayacak dil veya araç düzeyinde bir yöntem olmadığından tekrar yükü sürüyor

Son değerlendirme: güçlü ama maliyetli

  • Rust, sistem seviyesinde kod, CLI uygulamaları, web sunucuları ve web istemcilerini aynı dille yazabilecek kadar çok yönlü
  • WebAssembly kullanıldığında, aynı binary ile LLM’ler tarayıcıda ve komut satırında çalıştırılabiliyor
  • Rust programları son derece sağlam olabilir ve Rust’ın engellediği problemleri hissedince başka dillere dönmek zorlaşıyor
  • Kısa süreliğine Go’ya dönüldüğünde geliştirme hızı yeniden çekici geldi, ancak runtime panic yaşanınca bu avantaj sarsıldı
  • Rust’ın belirgin dezavantajları var
    • İşe alım zor
    • Öğrenme süreci yavaş
    • Hızlı iterasyon için fazla katı
    • Özellikle async kodda bellek ve performans sorunlarını takip etmek zor
    • Tüm kütüphaneler güvenli kod için yeterince iyi değil
    • Geliştirme araçlarında hâlâ önemli iyileştirme alanı var
  • Küçük bir ekiple şaşırtıcı işler yapıldı, ancak büyük engeller de vardı; ayrıca Wick için Rust’ı daha uygun kılan teknik nedenler bulunduğundan, Rust’ın Wick için buna değip değmediğine karar vermek için henüz erken olduğu düşünülüyor
  • Hızlı iterasyon gerekiyorsa Rust büyük olasılıkla uygun değil
  • Kapsam biliniyorsa veya daha yüksek başlangıç maliyeti karşılanabiliyorsa Rust ciddi biçimde değerlendirilebilir
  • WebAssembly perspektifi her ay daha da güçlenirken, bir kez yazılmış sağlam yazılımı birçok yerde yeniden kullanma olasılığı da giderek daha gerçekçi hale geliyor

1 yorum

 
GN⁺ 2023-10-26
Hacker News yorumları
  • Rust’ı çok kullandım ama yıllar geçse de hâlâ verimliliğinin düşük olduğunu hissediyorum
    Bu aralar daha çok Zig kullanıyorum; çünkü sadece yazmak istediğim koda odaklanabiliyorum ve hangi araç ya da kütüphaneyi kullanmam gerektiğini düşünmek zorunda kalmıyorum, bu yüzden kendimi yaklaşık 10 kat daha üretken hissediyorum
    Rust’ın bellek güvenliği sağladığını ve bunun önemli olduğunu biliyorum ama kullanılabilirliği gerçekten kötü. Rust kullandığım her seferde kısıtlanmış hissediyorum ve sürekli kütüphane aramam ya da bir işi nasıl yapacağımı araştırmam gerekiyor; bu yüzden doğrudan “kod yazamıyorum”
    Tür sistemi de kontrolden çıkmış gibi büyüyebiliyor ve belirli bir struct üzerinde gerçekte hangi metotları çağırabileceğini anlamanın zor olduğu pek çok an oluyor. Rust harika bir araç ve birçok sorunu çözüyor ama iyi bir genel amaçlı dil olduğunu düşünmüyorum

    • Bu his herkes için ortak değil. Kabuk betiğinden biraz daha karmaşık bir işse Rust kullanıyorum, hatta pencere yöneticimi de Rust programlarıyla kontrol ediyorum
      Python’ı neredeyse 20 yıldır kullanan biri olarak söylüyorum, artık Rust’ta da Python’daki kadar hızlı çalışıyorum
    • Katılıyorum. Şu anda Rust’tan çok C ve C++ içinde daha verimli hissettiğim oluyor
      Rust bana göre doğru denge noktasını tamamen kaçırmış gibi. Yüksek seviyeli uygulamalar yazmak için düşük seviyeli ayrıntılar konusunda fazla titiz; gömülü sistemler ya da işletim sistemleri içinse fazla karmaşık
      İlki için C++, Java, Haskell, OCaml, hatta Go’ya biraz C karıştırmayı seçerdim; ikincisi içinse makro assembly gibi kullanılan C çok daha uygun
      Graydon Hoare’in ilk tasarımı olan; lineer tipler, çöp toplayıcı, stack allocation, green thread’ler ve CPS içeren OCaml/SML yönünün çok daha iyi bir dil ortaya çıkaracağını düşünmeye devam ediyorum
    • Benim deneyimim tam tersi. Gömülü sistemlerde Rust kullanırken hem özgüvenim hem hızım ciddi biçimde arttı
      C’de küçük bir hata sık sık tanımsız davranışa ve baş ağrısına yol açarken Rust’ta bunun olmaması oyunu tamamen değiştirdi
    • Ne tür kod yazdığını merak ediyorum. Çok düşük seviyeli mi yoksa çok yüksek seviyeli mi?
      Zig’de kütüphane aramaya ya da bir şeyin nasıl yapılacağını öğrenmeye gerek olmadığını mı kastediyorsun?
    • Genel hissiyata katılıyorum ama bunu kelimelere dökmek zor
      Rust, her bit ve baytın nereye gideceğine, hangi thread’de kullanılacağına ve hangi mutasyon biçimiyle ele alınacağına önceden karar vermeni zorluyor. Parser ya da mikrodenetleyici düzeyi bir iş değilse bu süreç sıkıcı geliyor
      Önce bir şeyi çalışır hâle getirip sonra en iyi API yapısına karar verme yaklaşımını seviyorum ama Rust bu süreçle çatışıyor
      Rust’ın tür sistemi daha güçlü olsa da Swift ile de performansın %90’ını alabiliyorsun ve akış çok daha doğal geliyor
  • crates.io’da ad alanları olmaması en büyük eleştiri noktası olabilir
    Herkes genel ve küresel paket adlarını kapabiliyor ve crates.io deposundan kaçınmadığın sürece çoğunlukla buna katlanmak zorundasın. Üstelik böyle kapılmış genel adlı paketlerin bazıları gerçekten kullanılacak en iyi paketler de değil
    Java tarzı ters DNS gösterimi uzun ve can sıkıcı olduğu için buna bir tepki olmuş olabilir ama GitHub’daki gibi kullanıcı/grup ad alanını paket adının önüne koymak iyi bir orta yol olurdu gibi geliyor

    • crates.io’da isim kapıcılarını bulmaya yönelik bir analiz yapmıştım ve en üstteki kapıcının bir hafta boyunca yaklaşık her 30 saniyede bir crate oluşturduğu sonucuna vardım
      Bu analizi crates.io ekibine gönderdim ve otomasyon yasağını da işaret ettim ama bunun isim kapma için yeterli kanıt olmadığını söylediler
      crates.io’nun sorunu, net politikaları olsa bile bunları uygulamaması. Bu yüzden kısa ve akılda kalıcı crate adlarının hepsi çoktan alınmış durumda ve geri almanın da bir yolu yok
    • Bunun Java tarzı ters DNS’ye bir tepki olmaktan çok, o dönemde çoğu paket yöneticisinin benimsediği geleneği takip etmekle ilgili olduğunu düşünüyorum
      NPM, PyPI, RubyGems, Elixir’in Hex’i, Haskell’in Cabal’ı gibi örneklere bakınca Rust’ın çıktığı 2014~2015 döneminde Java dışı paket yöneticileri arasında tek küresel ad alanı kullanmayan pek örnek hatırlamıyorum
      Bazıları sonradan bunu düzeltmeye çalıştı ama o zamanlar paket yöneticileri genel olarak böyle çalışıyordu
    • Maven ve Java, bağımlılık yönetiminin iyi çalışması konusunda hak ettiği değeri görmüyor
      Sonradan çıkan diğer dillerin daha kötü bağımlılık yönetim sistemleri önceki örneklerden neredeyse hiçbir şey öğrenmedi
    • Paketlerde URL kullanmak oldukça mantıklı. Go ekosisteminde iyi çalışıyor
      Bunun bir avantajı da dil düzeyinde küresel bir paket veritabanına ihtiyaç bırakmaması. Paketi example.com/your-thing adresine koyduğunda fiilen anında yayımlamış oluyorsun
      Elbette istenirse ayrı olarak önbellek ve arama motoru da sunulabilir
    • Rust’ı sık kullanmıyorum ama bu tür sorunlar paket depoları genelinde gerçekten sinir bozucu
      Mesela http-server kötüdür, onun yerine MuffinTop kullanmalısın deniyor ve senin bunu sadece biliyor olman bekleniyor
      Resmî paket adı diye bir kavram ilginç ama zamanla takma adın arkasındaki kod değişirse aslında daha da kafa karıştırıcı olabilir
      Sonuçta bunun, hangi ekosistem olursa olsun o alanda uzmanlaşma sürecinin kalıcı bir parçası olarak kalacağını düşünüyorum
  • Çalışma alanı kökünde .cargo/config.toml oluşturursan bu tüm crate’lere uygulanır; böylece küresel Clippy lint ayarlayabilirsin
    Dosyada [build] altında rustflags = ["-Wclippy::lint_name_to_warn", "-Dclippy::lint_name_to_deny"] gibi yazman yeterli
    Ancak rustflags eklenerek değil üzerine yazarak çalışır; bu yüzden RUSTFLAGS ortam değişkeni gibi başka bir kaynaktan gelen ayarlar varsa bunun üzerine yazılır

    • Biz commit sırasında lib.rs ya da main.rs dosyalarına lint ekleyen bir script çalıştırıyoruz. Basit
  • Rust'un mesleki olarak önemli hale geleceği açık göründüğü için öğreniyorum. Gerçekten sevmek istiyorum ve avantajlarını da görüyorum ama şimdiye kadar kullandığım diller arasında en rahatsız edici olanlardan biri
    Ustalığım arttıkça bu hoşnutsuzluğun kaybolacağını ummaya devam ettim ama öğrenme eğrisinde yükseldikçe özel bir yakınlık da oluşmadı
    Sorun değil. Ustaca kullanıp da sevmediğim tek dil bu olmayacaktır. Sadece Rust'ı sevdiğini söyleyen o kadar çok kişi var ki benim de keyif alacağımı sanmıştım

    • Karşı örnek olarak, ben Rust ile programlama yapmayı seviyorum. Borrow checker ile boğuştuğum dönem çoktan geride kaldı ve bugünlerde, türleri kontrol etmek için bilerek tetiklediğim durumlar dışında hata da nadir oluyor
      Rust derleyicisi de geçerli olan daha geniş durumları kabul edecek şekilde iyileşmiş gibi görünüyor
      Borrow checker'ı anlamanın anahtarı, temelindeki bellek modelini anlamaktı. Rust'ın bellek modeli, generic gibi soyutlamalar için yapılan genişletmeler dışında C ile aynı
      Borrow checker kuralları ilk başta keyfi görünüyor ama bu bellek modeliyle derinden bağlantılı. Borrow checker'a istemeden takıldığım anlar aslında en değerli olanlar; çünkü bunlar dikkatsizlikten doğan hatalar oluyor
      Asıl korkutucu olan, C ya da C++ gibi dillerde böyle kodların olduğu gibi kabul edilip devam edilebilmesi
      Rust'ın katı tür sistemi ve borrow checker'ı, kodu doğru şekilde yapılandırmaya nazikçe yönlendiriyor ve kullandığım tüm dillerde kod tasarımımı iyileştirdiğine eminim
    • Rust öğrenmeye birkaç kez çalıştım ama hep geri sekiyorum. Sanki kullanılabilirliği iyi değilmiş gibi geliyor
    • Hâlâ takıldığım nokta, varsayılan/adlandırılmış fonksiyon argümanları olmaması
      Bu, popüler dillerin çoğunda bulunan çok temel bir programcı kullanılabilirliği özelliği ve C++'ta bile uzun zamandır varsayılan argümanlar var
    • Neyi sevmediğini merak ediyorum
  • 10 yıl boyunca neredeyse her hafta pthread çağıran eski bir C/C++ programcısıyım; şimdi ise her yerde asenkron Rust kullanıyorum
    Asenkronun neden bu kadar nefret gördüğünü anlamıyorum. Bence herkes her şeyde asenkron kullanmalı. Görünüşte tek iş parçacıklı olan “basit” işler de dahil

    • Bence sorun bulaşıcı olması. Özellikle gömülü ya da Wasm ortamlarında, ana akım asenkron tam da istediğim asenkron olmayabiliyor
      Yazarın kullanım senaryosu Wasm idiyse kesinlikle farklı bir bakış açısı oluşurdu
      Büyük tamponlar kullanan ya da tahsis maliyetinden kaçınmak için bunları yeniden kullanan işler, eski usul thread pool yaklaşımından sık sık fayda görüyor. Bump allocator veya shard allocator ile bu kısmen çözülebilir ama vektörleştirilebilir sıkı döngülerde CPU'ya bağlı durumlarda thread pool daha iyi çalışıyor
      Asenkron iyi bir araç ama yalnızca en iyi olduğu bağlamlar yok
    • İç içe asenkron çağrılarda hata işlemenin Go'dan nasıl farklı olduğunu karşılaştırmak için yakın zamanda biraz asenkron Rust denedim ama yazmak istediğim basit örnek bile Tokio olmadan yapılamıyor gibi göründü
      Go, C# ve TypeScript'te böyle bir engel yok
      Örneğin, Tokio'dan gelen dekoratör olmadan main fonksiyonu içinde bile await kullanılamıyor gibi duruyor
    • Şu anda takıldığım sorun, rhai Engine gibi bazı öğelerin Send olmaması ama benim bunları asenkron closure içinde kullanmaya çalışmam
      GPT-4, bir thread içinde tokio Runtime oluşturup block_on() kullanmamı önerdi. Yarın deneyeceğim. Bu benim ilk ciddi Rust projem
    • Ben tam tersini öğrendim. Programcılar gerekmediği hâlde her şeyi gereksiz yere asenkron yapma eğiliminde oluyor; bu da karmaşıklığı ve zihinsel yükü artırıyor
    • Biraz daha ayrıntı verebilir misin? Görünüşte tek iş parçacıklı basit işlerde asenkronu seçmeye değer bir örnek ne olur merak ediyorum
      “Artık her yerde asenkron Rust kullanıyorum” derken bunun “her yerde Tokio kullanıyorum” anlamına gelip gelmediğini de merak ediyorum
  • Rust ile programlama, istismarcı bir ilişkiye gerçekten benzemiyor. Derleyici mümkün olduğunca yardımcı olmaya çalışıyor; özellikle rustc hata mesajları dünya çapında en üst seviyede

    • İşletim sistemi, programcının kaynakları doğru şekilde ele almasını bekler ve Rust derleyicisi bunu çok kolay hale getirir
      İstismarcı ilişkiye daha yakın olan şey Rust derleyicisi değil, işletim sistemidir. Donanım da assembly'yi doğru çalıştırmanızı beklediği için o açıdan bakarsanız o da istismarcı bir ilişki sayılabilir
      Rust'ın hata mesajları rakipsiz ve buna yaklaşan başka derleyici yok
      Ayrıca kısa süre önce LaTeX kullandım ve hata mesajları berbattı. Neyin yanlış olduğunu hatalara bakarak anlamaya çalışmak tam bir kâbustu
    • Genel olarak iyi ama asenkron fonksiyonlar içindeki herhangi bir hatanın, tüm özyinelemeli çağrı noktalarında Future'ın artık Send ve Sync olmadığını söyleyen hatalar üretmesinden gerçekten nefret ediyorum
      Konsol baştan sona hatayla doluyor ve asıl sözdizimi hatası aralarda bir yere gömülüyor
    • Rust derleyicisi, gördüğüm derleyiciler arasında “perhaps” kelimesini kullanan ilk derleyiciydi
      Asıl şikâyetim, hâlâ lifetime'ları tam olarak anlamıyor olmam ve derleyicinin de her seferinde yardımcı olamaması. Bu anlaşılır bir şey çünkü derleyici temkinli davranıyor
  • C++ testlerinde sıkça “derleniyorsa büyük ölçüde doğrudur” denir
    Rust’ın birçok hatayı ele alması yüzünden yaygın test örneklerinin anlamsızlaştığını düşünüyorsanız, bunu diğer dillerde doğru olan şeyi test etmediğinizin bir işareti olarak görürüm
    Test edilmesi gereken şey dilin kendi sorunları değil, iş mantığıdır
    Test koduna bakıp “JavaScript olsaydı bunu test ederdim ama Rust’ta gerek yok” diye hissediyorsanız, o testi doğrudan silebilirsiniz

    • “Derleniyorsa büyük ölçüde doğrudur” sözünü Haskell ve Rust için duydum ama bunun C++ için uygulandığını hiç duymadım
    • null pointer istisnası iş mantığını bozan bir bug’dır
      “İş mantığına karşı dil sorunu” diye bir ayrım yoktur. Çünkü dil, iş mantığının üzerine kurulduğu zemindir
      Başarısızlık biçimlerini test etmiyorsanız testin anlamının ne olduğunu bilmiyorum
    • Bozuk çöp kod derlendi diye muhtemelen doğrudur sanan C++ programcısı tipinde tuhaf bir görkem var
      Aşina olduğum çoğu dilin aksine C++’ta IFNDR vardır ve bu, şaka yollu “bu bir C++ programı mı?” sorusuna verilen yanlış pozitif diye anılır
      Standarda uygun bir C++ derleyicisinin, yazdığınız kodun anlamsız olduğundan şüphelenilen bazı durumlarda bunu size bildirmesi yasaktır; onun yerine devam edip bir şeyler üretmek zorundadır
      Bu çalışan bir yürütülebilir dosya da olabilir, her cuma büyük felaket çıkaran bir yürütülebilir dosya da olabilir. Bunu bilmenin yolu yoktur
      ISO standardı bu tür durumları tanımlar ama o kadar muğlaktır ki nelerin dahil olduğunu tam olarak belirlemek zordur; benim tahminim, günümüzde trivial olmayan çoğu C++ yazılımı fiilen IFNDR’dır. En iyisi dili toptan reddetmek
  • Rust, programcının derleyicinin yaptığı her şeyi tamamen kontrol etmesi ve bilinçli olması gerektiği fikrini sonunda kırmış gibi görünüyor
    Aslında bu onlarca yıldır böyle değildi ve derleyiciler neredeyse büyü gibiydi. Rust, borrowing ile bu gidişatı büyük ölçüde tersine çevirip insanları derleyicinin kendilerinden daha iyi bildiği fikriyle rahat ettirdi
    Bunun daha da ileri gitmesini isterdim. Algoritmik olarak gerekli değilse koleksiyonları açıkça baştan sona yinelemek zorunda olmamalıyız. Çeşitli işler örtük olarak paralelleştirilmeli. Rust usulü bir Bash güzel olurdu

    • Bu, Rust deneyimimle tamamen ters düşüyor
      Rust ne yaptığını oldukça şeffaf biçimde gösterir ve derleyici sihri konusunda çok muhafazakârdır. Dil örtük heap allocation yapmaz, reference counting yapmaz, örtük sayısal tür dönüşümleri de yoktur
      Örtük olarak kopyalanabilir diye bildirilmemiş türleri kopyalamaz; bu bile yalnızca basit, sığ bir memcpy ile kopyalanabilen türlerde yasaldır
      Rust her yerde sıfır maliyetli soyutlamalar kullanır; bu yüzden hangi koda derleneceği tahmin edilebilirdir ve genelde basittir. Standart türlerin varsayılan yerleşimi de iyi bilinir; bu yüzden Vec üzerinde dolaşmanın pointer artıran bir döngüye derleneceğini bilirsiniz ve örtük paralellik yoktur
      borrowing’i “derleyicinin programcıdan daha iyi bilmesi” diye tarif etmek tuhaf. borrowing, tür denetimine benzer. Bir türü geçici diye tanımlayıp sonra uzun ömürlüymüş gibi kullanmaya çalışırsanız hata alırsınız
      Bu, Foo struct’ı döndürdüğünü beyan eden bir fonksiyondan Bar döndürünce hata almakla aynıdır. Derleyicinin “daha iyi bilmesinin” nedeni sadece sizin bug yazmış olmanızdır
      borrowing de garbage collection olmadan doğrudan pointer kullanımı olarak derlenir ve C ABI struct’larında ve fonksiyonlarında birebir C pointer’ı ile aynı olduğu garanti edilir. Derleyiciden daha iyi bildiğinizi düşünüyorsanız ömürleri unsafe ile aşabilirsiniz
    • Paralel iterator sağlayan crate’ler zaten var. Sadece iter() çağrısının adını değiştirmeniz yeterli
      Ama bunun örtük olması gerektiğine katılmıyorum
    • “Derleyicinin yaptığını kontrol edememek” ifadesi biraz abartılı
      Bazı açılardan Rust, programcıya C’den daha fazla kontrol verir. Örneğin Rust inline assembly’yi standart olarak desteklerken, C’de inline assembly tedarikçi bazlı eklentilere dayanır
      Ama rahat varsayılanlar çok farklıdır. Rust’ta güvensiz tür dönüşümleri çok prosedür ve dikkat gerektirir, C’den daha fazla kurala uymanız gerekir
      Özellikle Rust referansları fiilen bütünüyle restrict gibi davranır; ham pointer’dan güvenli referansa unsafe cast yaparken bunu bozmak çok kolaydır. Bu yüzden seçeneğiniz varsa böyle kod yazmamak için güçlü bir teşvik oluşur
    • Tagged pointer gibi şeyler de dahil olmak üzere çok fazla unsafe Rust kullanan biri olarak buna kesinlikle katılmıyorum
      Tam tersine, daha açık denetim istiyorum ve bu yükü azaltmak için daha ifade gücü yüksek bir tür sistemi isterim. İdeal olarak Rust’ın tür sistemi Prolog’un bir varyantı gibi olsa harika olurdu
    • “Rust usulü Bash” varsa, bu türlerin — özellikle kayan noktalı sayıların — bulunduğu, istisnai durumların daha az olduğu, açık parametreli fonksiyonlara ve basit komut satırı bayraklarına sahip bir Bash olurdu
  • Tür kısıtlarına ne zaman yatırım yapıp ne zaman yapmayacağını öğrenmek önemli bir derstir
    Bu yalnızca Rust’a özgü bir sorun değil ama ifade ediliş biçimi biraz farklı olabilir
    Aşırı türlendirilmiş C++ ve aşırı soyutlanmış ve türlendirilmiş Java ile çalıştım; ikisi de aynı türde refactoring sorunlarına sahip
    Tersine, yetersiz türlere ve yetersiz dokümantasyona sahip çok fazla Go da gördüm; burada belirli değerler oraya buraya saçılıp çalışma zamanında mayına dönüşüyor ve refactoring gerçekten çok ciddi biçimde zorlaşabiliyor
    Başlangıçtaki ilerleme hissi daha hızlı geliyor ama çoğu zaman bug’ları kullanıcıya dağıtmış oluyorsunuz
    Bu ödünleşim için sihirli bir doğru cevap yok. Rust bu eksende epey geniş bir seçenek yelpazesi sunuyor

  • “Rust bütün gün, her gün, önceki hayatında tamamen normal sayacağı şeyler hakkında bağırıyor” sözüne gelince, iyi bir C derleyicisi de tüm bayraklar açıldığında benzerini yapar
    İsteğe bağlı olarak bu bağırmayı kapatmaya ve bilerek kötü kod yazabilmeye izin veren dilleri ve derleyicileri seviyorum. Hızlıca yazılabilen, çalışan kötü kod; mükemmel ama sonsuza kadar süren koda kıyasla çoğu zaman daha iyidir
    Kötü ama çalışan bir kavram kanıtı yapıp sonra onu daha az kötü hale getirecek şekilde düzeltebilirsiniz
    “Yeni kullanıcıları iyi çekiyor ama kütüphaneler ya da araçlar dramatik biçimde iyileşmiyor, sadece belirli kullanım senaryolarını ele alan tek seferlik fork’lar çıkıyor” noktası yaşla ilgili değil
    Çekirdek geliştiricileri çekmek zordur ve bunu cazip hale getirmek için çok çaba gerekir. Üstelik kültürel teamülleri erken benimseyenler belirler ve teamüllerin hiç olmaması da çoğu zaman kötü teamüller kadar zararlıdır
    Python’a bakınca, geliştirme ve çalışma ortamlarına gevşek yaklaşmanın sonucu olarak Python programı geliştirme ya da çalıştırma konusunda yaklaşık 50 farklı yol birbiriyle rekabet eder hale geldi
    En çok kullanılan paket deposu PyPI yıllarca berbattı; mevcut paketlerin üzerine inşa eden az kişi var, adlar rastgele sözcük üretecinden çıkmış gibi görünüyor, ekosistemde çok sayıda kötü amaçlı yazılım var ve komut satırından paket araması bile yapılamıyor
    Bu dilin suçu değil, seyirci gibi kalan topluluğun ve çekirdek ekibin suçu. Kültür, merkezindeki teknolojiden daha önemlidir
    Burada özellikle Python’ı hedef alıp eleştirmiyorum; sadece o sorunları daha iyi biliyorum. C yarım yüzyıldır var ama onun topluluğu da daha modern dillerin sunduğu çözümlerin yarısını bile düzgünce toparlayabilmiş değil

    • Rust da bunu destekliyor. Her şeyi unsafe olarak işaretlemeniz yeterli
    • “İyileştirilmiş kütüphaneler yok” diye Linux ve Windows’ın bileşenleri Rust’a port etmeye başlamış olması pek olası görünmüyor
    • Cesurca söylemek gerekirse, bu TypeScript’e çok benziyor
      Derleyici düzeltmen için bağırıyor ama sen her şeyi kusursuzca parlatmadan önce sadece fikri denemek istiyorsun