NOT 0018 / SİSTEMLER

Neden Rust

16 Eylül 2026Emir Hüseyin İnci8 dkEnglish

Hız için değil. Çekirdekleri Rust'ta yazmamın sebebi şu: kurduğum her şey aynı sözü veriyor — aynı girdi aynı çıktıyı üretir, ve bunu kontrol edebilirsin — ve o söz programın ne kadar hızlı koştuğuyla ilgili değil. Onun ne yapacağını ve ne yapmayacağını ne kadar net söyleyebildiğimle ilgili.

Para float olmamalı

Calybris bir karar çekirdeği: içeri katalog, politika ve istek; dışarı bir karar ve replay edilebilir bir denetim paketi. Ürünün tamamı o replay. Aylar sonra biri log'u yeniden koşturuyor ve birebir aynı kararı alıyor, ya da sistemin hiçbir değeri yok.

Kayan nokta bunu sessizce bozuyor. Hatalı olduğu için değil — sıraya bağlı biçimde hatalı olduğu için. Aynı sayıları farklı sırada toplarsan farklı bir toplam çıkıyor, ve fark, bir bütçe bir kuruş aşıp reddetmesi gereken şeyi onaylayana kadar görünmüyor.

Bu yüzden sayısal yolda sıfır kayan nokta var. Değerler sabit noktalı tam sayı. Başka yerlerde, analiz kodunda float kaçınılmaz olduğunda, tam sayılar i128'de ve float'lar satır sırasında Neumaier telafisiyle toplanıyor — böylece bir toplam sessizce eksiye düşemiyor ve batch boyutuyla oynayamıyor.

Bana "bu yolda float yoktur" dedirten ve derleyiciyi buna şahit tutan bir dil, bir yorum satırının yapamayacağı bir iş yapıyor.

Eşzamanlılık tarafı da aynı argüman. Bütçe kontrolü ile borçlandırma iki ayrı gözlem olamaz; arada başka bir thread harcayabilir. Rust geçişi tek bir durum makinesi adımı olarak modellememe, sonra da paylaşılan defterin etrafındaki zamanlayıcı sıralamalarını Loom ile saymama izin verdi. Test edilen özellik "kilit doğru görünüyor" değil. Keşfedilen hiçbir yürütmenin var olandan fazla bütçe onaylamaması.

Söylenebilir bir sınır

ProofFrame belleğe sığmayabilecek veri setlerini doğruluyor. Varsayılanları 512 MiB bellek ve 4 GiB geçici depolama; bellek bütçesi sonradan gözlenmiyor, her tahsisten önce düşülüyor, ve bunu aşacak bir tarama büyümek yerine hata veriyor. spill="never" dersen diske hiç dokunmadan reddediyor.

Bu, baskı altındaki davranış hakkında önceden verilmiş bir taahhüt. Aynısını bir Python pipeline'ı için dürüstçe nasıl yazacağımı bilmiyorum — Python dikkatli olamadığı için değil, tahsisi düşecek olan ben olmadığım için.

Bir doğrulayıcı hakkındaki ilginç soru asla temiz veride ne kadar hızlı koştuğu değil. Veri makineden büyük olduğunda, şema yanlış olduğunda ya da geçici dizin salt okunur olduğunda ne olduğu. Her biri adı olan bir hata olmalı ve her birine bir testten ulaşılabilmeli.

Tek motor, üç yüzey

Beni asıl ikna eden argüman bu, ve görmem zaman aldı. ProofFrame komut satırı aracı olarak, PyO3 üzerinden Python paketi olarak, ve WebAssembly'ye derlenip tarayıcı sekmesinde koşuyor. Tarayıcı demosu ne yeniden yazım ne de kayıt. Bir inceleme render ettiğinde crate'in review_html fonksiyonunu çağırıyor — CLI'ın dosyasını yazarken kullandığı derlenmiş fonksiyonun aynısı. JavaScript'te hiç HTML kurulmuyor. Tarayıcıdan kaydedilen inceleme, CLI'ın ürettiği dosyanın bayt bayt aynısı.

Üç teslim yüzeyi, cevabın ne olduğuna dair tek tanım. Diğer versiyonunu da yazdım: bir Python uygulamasıyla bir JavaScript uygulaması anlaşmak zorunda — ve anlaşıyorlar, ta ki bir kenar durum gelene kadar; ondan sonra ikisinden yalnızca biri haklı. İki uygulamayı senkron tutmak zor bir problem değil. Bitmeyen bir problem.

WebAssembly bunun görünür karşılığını verdiği yer: analiz motoru ziyaretçinin sekmesinde koşuyor ve hiçbir dosya hiçbir yere yüklenmiyor. Bu bir performans özelliği değil. Çekirdek taşınabilir olduğu için elde edilen bir gizlilik özelliği.

Rust'ın yakalamadığı hata

Bu bir reklam gibi okunmasın diye karşı örnek — ki bana bir sonuca mal oldu. Trading araştırmamda maliyet tablosundaki komisyon sabiti 70_000'di; yanındaki yorum 7_000_000 diyordu. Yüz katlık bir hata, üstelik ham spread'li bir hesabın perakendeden ucuz olup olmadığına karar veren bir sayıda. Yanlış sabitle ucuzdu. Düzeltilince ham hesap ikisinden pahalı olanı çıktı ve koca bir akıl yürütme hattı tersine döndü.

Rust bir i64'e atanan bir i64 gördü ve haklı olarak memnun oldu. Tip sistemi, birimi bir tip yapmadığın sürece bir birim hatasını yakalayamaz — ben de yapmamıştım. "Bu sayı centi-lot başına mikrokuruş cinsindendir" için borrow checker yok.

Onu yakalayan şey birimi sabitleyen bir test oldu. Dil değil.

Rust bir hata kategorisini kaldırıyor ve bir üstündekine dokunmuyor. Bellek güvenliği ve veri yarışı yokluğu gerçek şeyler, ama bana para kaybettirecek hatalar onlar değildi. Yanlış sabitler, yanlış birimler ve yanlış varsayımlar kaybettirecekti — ve onlar dilden bağımsız. Hatta küçük şeyleri yakalayan bir derleyici, büyüklerin de yolunda olduğuna inanmayı kolaylaştırıyor.

Nerede kullanmıyorum

O sınırın en net hali tek bir küçük deponun içinde. ForecastEdge otuz şehir için iki yıllık arşiv tahmini puanlıyor ve bir tarafı Python, diğer tarafı Rust. Arşivi indirmek tamamen ağ beklemek: dille ilgili hiçbir şey sonuca ulaşmıyor, ve bitirmeye en kısa yol Python. Puanlama ise 1,68 milyon bootstrap değerlendirmesi, ve oradan yayınlanan her rakamın yeniden koşuda aynı gelmesi gerekiyor. Bir tarafta beklemek, diğer tarafta garanti etmek — çizgi benim tercihimin olduğu yere değil, işin türünün değiştiği yere düşüyor.

Python binding'leri de aynı mantık. Veri doğrulayan insanlar Python'da çalışıyor, ve onlardan not defterinden çıkmalarını istemek gelmemelerini istemek demek. Rust altta, garanti edilebilecek şeyi değiştirdiği yerde; Python üstte, birinin gelip gelmeyeceğini değiştirdiği yerde.

Rust kısıtları da kaldırmıyor, görünür kılıyor. WebAssembly hedefinin dosya sistemi yok ve kesin küme yolu geçici bir dizine taşıyor; bu yüzden tarayıcıda kesin kurallar sessizce yaklaşıklanmıyor, motora ulaşmadan reddediliyor. Doğru davranış, ve hâlâ eksik bir özellik. Taşınabilirlik bir yüzey kazandırdı, bedava öğle yemeği değil.

Peki ne zaman

Bunları kurduktan sonra vardığım kural — öncesinde değil:

Yanlış cevabın pahalıya patladığı ve programın neyi reddedeceğini önceden, yazılı olarak söylemen gereken yerde Rust'a uzan.

Hız da satılır, tersini iddia etmiyorum. Ama hız geri dönüp iyileştirebileceğin bir sayı, ve çoğu zaman onu iyileştirmenin en ucuz yolu dil değiştirmek değil bir şeyi yapmayı bırakmak. Garanti öyle değil. Determinizm, baskı altında tutan bir sınır, birkaç yüzeyin arkasında tek uygulama — bunları ya baştan içine koyarsın ya da sende yoktur; sonradan gelen hiçbir optimizasyon turu birini eklemez.

Geri kalan her yerde — yapıştırıcı kod, veri çekme, keşif, ve henüz ne kurduğunu bilmediğin kısım — derleme süresi karşılığında hiçbir şey olmayan bir vergi. Çekirdekte ödüyorum, kenarlarda ödemeyi reddediyorum. O çizginin nereye düştüğü, asıl tasarım kararı.