2 puan yazan GN⁺ 2026-06-12 | 1 yorum | WhatsApp'ta paylaş
  • 2000’lerden 2010’ların başına kadar statik tiplemenin popülaritesinin düşüp 2010’ların orta-son döneminde yeniden yükselmesinin nedeni, bir moda akımı değil statik tip sistemlerinin kalitesindeki artış
  • Çukur kazarken kağıttan yapılmış bir kürek yerine çıplak elle kazmak daha iyiyse, berbat bir statik tip sistemi yerine dinamik tip sistemi daha iyidir
  • Erken dönem Java veya C++98 gibi geçmiş statik tip sistemleri nullable ile non-nullable ayrımını bile yapamaz, toplam tipleri yoktur ve tip adlarını tek tek yazmak gerekir
  • TypeScript, Haskell, Swift, Rust gibi modern tip sistemleri null ayrımı, toplam tipler/union type, tip çıkarımı özelliklerini varsayılan olarak sunar
  • IDE’lerde metot otomatik tamamlama özelliğinin yaygınlaşmasıyla, statik tiplere girilen bilgi hata denetiminin ötesinde ek üretkenlik de getirir

Statik tiplemenin popülerliğindeki değişime dair bir hipotez

  • Statik tiplemenin 2000’ler ile 2010’ların başında popülerliğini kaybedip 2010’ların orta-son döneminde yeniden artması olgusu,
    programlamanın modayla yönlenen bir sektör olmasından değil, yaygın kullanılan statik tip sistemlerinin kalitesinin iyileşmiş olmasındandır

Kürek benzetmesi — seçimi belirleyen şey aracın kalitesi

  • Çukur kazarken kürek işe yarıyorsa elbette çıplak el yerine kürek kullanılır; ancak
    eldeki tek kürek kağıttan yapılmışsa, toprağı anlamsızca karıştırmaktan başka işe yaramaz ve bu durumda çıplak elle kazmak daha iyidir
  • Dinamik tip sistemlerinde değişkenlerin ve alanların durumunu/içeriğini tamamen kendi zihninizle takip etmeniz gerekir;
    bilgisayar ne yardım eder ne de engel olur, yani bu çıplak elle kazmaya karşılık gelir
  • 1990’larda ve 2000’lerin başında yaygın olan yetersiz statik tip sistemleri kağıt kürek gibiydi
    • nullable ve non-nullable pointer ayrımı gibi basit bir konuda bile yardımcı olamazdı
    • yalnızca çarpım tipleri (product type) vardı, toplam tipler (sum type) yoktu
    • tip adlarını pek çok yere elle yazma yükü vardı
    • BufferedReader bufferedReader = new BufferedReader(new FileReader(filename)); gibi kodlar küçük bir felaketti

Modern tip sistemlerinin her zaman sundukları

  • TypeScript, Haskell, MyPy, Swift, Rust gibi modern tip sistemleriyle karşılaştırıldığında artık her zaman aşağıdakiler sunuluyor
  • nullable ile non-nullable ayrımı

    • Haskell Maybe t, TypeScript T | null, Swift T?, Rust Optional<T> sunar
    • Tip sistemi, null kontrolü gereken tüm noktaları ve eksik olup olmadıklarını kolayca gösterir
    • Uygulamada çalışma zamanında null pointer hatası neredeyse hiç görülmez
  • toplam tip veya union type

    • "Geçersiz durumları ifade edilemez hale getirmek (Make invalid states unrepresentable)" pratiğini mümkün kılar
    • Birden fazla alana sahip durum makinesi (state machine) nesneleri oluşturulabilir ve her alan yalnızca sistem ilgili durumdayken var olur
  • tip çıkarımı

    • Derleyici let x = 5; ifadesinin bir sayı olduğunu anlayabildiği için let x: number = 5; yazmak gerekmez

IDE özelliklerinin yaygınlaşmasının kattığı fayda

  • Metot adı otomatik tamamlama gibi IDE özelliklerinin yaygınlaşması, statik tip sistemlerinin kullanışlılığını artırdı
    • 1990’larda Visual Studio’nun Intellisense özelliği ayırt edici bir avantajdı; 2020’lerde ise benzer işlevler neredeyse tüm IDE ve editörlerde bulunuyor
    • Statik tip sistemine verilen bilgiler, hata denetiminin yanında ek üretkenlik avantajlarına da dönüşüyor

Sonuç

  • İyi bir dinamik tip sistemi, kötü bir statik tip sisteminden daha iyidir
  • Ancak artık geçmişe kıyasla çok daha iyi statik tip sistemlerine sahibiz

1 yorum

 
GN⁺ 2026-06-12
Lobste.rs görüşleri
  • Bu yazı iyi ama tamamen katılmıyorum. 2000'lerin başındaki statik tip sistemleri harika olmasa da, hiç statik tip olmamasından çok daha iyiydi diye düşünüyorum
    Kapalı toplam tipler yoktu ama alt tipleme ile bunun önemli bir kısmı modellenebiliyordu; null olmayan tipler yoktu ama C++ referansları ve pointer olmayan tipler, ayrıca Java'nın ilkel tipleri bunun bir kısmını üstleniyordu. Ruby ya da JavaScript'te ise tüm tipler yalnızca null olabilir olmakla kalmıyor, aynı zamanda string gibi de, integer gibi de, programdaki diğer tüm tipler gibi de ele alınabiliyordu; bu daha kötü bir durumdu
    Statik tiplere yönelik akımın değişmesinin büyük bir nedeni, Web 2.0 sosyal ağ patlaması sırasında ilk davranan avantajının her şeyden önemli olmasıydı diye düşünüyorum. Ruby ya da Python ile teknik borç biriktirseniz bile hızlı çıkış yapıp iterasyon yapmak, Friendster ya da Digg gibi geride kalmaktan daha iyiydi; yavaşsanız da o dönemde kolay bulunan düşük faizli parayla daha fazla sunucu satın alabiliyordunuz
    Sonraki mobil patlamada ise yazılım, kontrol edemediğiniz kısıtlı kullanıcı cihazlarında çalışmaya başladı; yavaş dinamik tipli uygulamalar gerçekten yavaştı ve tip hatası olduğunda da sunucudaki gibi en üst düzey yanıt işleyicisiyle zarifçe toparlamak mümkün değildi. O ortamda statik tiplerin güvenliği ve performansı çok daha ikna edici hale geldi

    • Java ve 90'lar usulü C++'ı dinamik tipli dil kod tabanlarıyla karşılaştırıp hata oranlarının benzer olduğunu söyleyen epey makale var ve dinamik dil taraftarları bunu sık sık statik tiplerin faydalı olmadığına kanıt olarak öne sürüyor
      2000'lerin başında ben de katılıyordum, çünkü o dönemin tip sistemleri çoğu zaman neredeyse hiç yanlış çıkmayan özellikleri zorunlu kılarken kodu yapılandırmaya yardımcı olmayan kısıtlar dayatıyordu. Özellikle alt tipleme ile uygulama kalıtımının birleştiği biçim esnek değildi
      Daha modern tip sistemleri kullandıktan sonra fikrim değişti. snmalloc'ta C++ tip sistemiyle bellek sahipliği durum makinesi zorlanıyor; başka kod tabanlarında ise ring buffer sayaçlarının doğru overflow davranışı denetleniyor. İkisi de yanlış olduğunda debug etmesi uğraştırıcı ve yaygın hata kaynakları; derleyicinin, gerçekten doğru sandığım kodda derlemeyi reddedip hatanın ana dala girmesini engellediği durumlar oldu
    • Dinamik tipli dillerle geliştirmenin statik tipli dillere göre daha yavaş olduğunu düşünüyorum. Sürekli tersini iddia edenleri görüyorum ama anlayamıyorum
      IDE'de . tuşuna basıp metod adını biraz yazdıktan sonra doğru adayda Enter'a basmak, her birkaç saniyede bir 2 saniye kazandırıyor; hangi metodların olduğunu bilmediğinizde sınıf tanımını aramak için harcanan 30 saniyeyi de kurtarıyor. Bu ilke https://grugbrain.dev/#grug-on-type-systems içinde de iyi anlatılmış
      Bir fonksiyonun parametre tiplerini yazmaktan çok, metod çağıran kod satırları yazıyoruz; bu yüzden takas dinamik tipler aleyhine ezici biçimde kötü. Değerli olan şey, çalışma anında patlayacak saçma kodlara izin vermek değil, yerel değişken tiplerini atlayabilmekti; statik tipli dillerin bunu en başta yasaklaması gerekmiyordu
    • 2000'lerin başındaki popüler tip sistemleri sadece “muhteşem değildi” düzeyinde değil, gerçekten kötüydü ve aşırı ayrıntılıydı
      Tip sistemini ciddiye alan ender kod tabanlarında, hiçbir şey söylemeyen kodlar sayfalarca birikiyordu; buna rağmen çalışma zamanı koşulları dağ gibi kalıyordu ve Java'da tip hiyerarşisi büyüdükçe program da fiilen yavaşlıyordu. Kod tabanlarının çoğu tipleri seyrek kullanırken bol miktarda çalışma zamanı koşulu ekliyordu; ihtiyaç duyulan test kapsamı açısından dinamik tip sistemlerine kıyasla büyük bir tasarruf da sağlanmıyordu
      Dinamik tipli diller statik ödüller sunmuyordu ama kısa ve özdü; okumak, gözden geçirmek ve test etmek daha kolaydı. Özellikle 90'ların sonu ile 2000'lerin başındaki bağımlılık enjeksiyonu framework'leri gibi, her yeni servis eklediğinizde birden fazla XML dosyasını düzenlemek zorunda kaldığınız ortamlarda bu daha da belirgindi. RAM'in yarısını yiyen bir IDE olmadan da çalışabiliyordunuz
      Kariyerimin ilk dönemi tam olarak böyle geçtiği için yazıya tamamen katılıyorum. Java 1.4'ten Java 6'ya kadar maliyet/fayda oranı o kadar kötüydü ki statik tipli dillerden neredeyse vazgeçmeme neden oldu; birkaç yıl sonra hobi olarak Haskell kurcalayınca ancak statik tiplerin de makul bir maliyet/fayda oranına sahip olabileceğini, asıl sorunun Java olduğunu anladım. “python is not java” makalesi de o karanlık dönemi iyi yansıtıyor
    • Kalıtım temelli alt tipleme daha da zayıftı. Kapsamlılık denetimi yapan pattern matching'in kullanılabilirliğini sunamıyor ve uygulamayı birden çok yere bölüyordu
    • Rakiplerden önce siteyi yayına alıp kullanıcıların önüne koymanın ve ölçek ekonomisini kilitlemenin önemli olduğu açıklaması, bugünün durumu için de oldukça tanıdık geliyor
  • Statik tiplerin zamanın ruhu haline gelmesinden sonra yazılımlarımızda güvenilirlik kazancını gerçekten görüp görmediğimizden şüpheliyim
    Statik tiplerin avantajının daha çok anlık geliştirme geri bildirimi ve ölümcül çalışma zamanı hatalarını azaltmakta olduğunu düşünüyordum; teoride böyle hatalar her zaman mümkün olsa da pratikte o kadar sık yaşanıyor gibi gelmiyordu

    • Gördüm. Azımsanmayacak büyüklükte bir TypeScript kod tabanında TypeScript hata sayısını 0 yapmayı hedeflemeye başladıktan sonra undefined ve null üzerinde metot çağırma girişimleri keskin biçimde azaldı
      Junior geliştiriciler ve bazı seniorlar başta her yere @ts-ignore serpileceği konusunda şüpheciydi, ama gerçekte kırık bağımlılık tiplerinden kaynaklananlar dahil toplamda üç kadar oldu. Eskiden geliştirme branch'inde tip karışıklığı yüzünden haftada bir uygulama çöküp işimi engellerdi; şimdi bunun en son ne zaman olduğunu bile hatırlamıyorum
      Sadece tscyi tatmin etmek bile, kodu bizzat benim yazmadığım durumlarda dahi tip kaynaklı bugları azalttı. Buna karşılık günümüzde lint araçları aşırı hevesli; Sonar gibi araçları memnun etmeye çalışırken gerçek refactor kırılmaları gördüm. Uyarıların %95'i sahteydi, %3'ü aracın kendi bug'ıydı, işe yarayan %2 bile gerçek bug'ın kök nedeni değildi. Kod tabanını kurallara uydurmak için 1 hafta harcayıp bir bug yakalamak yerine, o süreçte iki tane daha ekledim
      tscyi tatmin etme çalışması kabaca günde 2 gerçek bug düzeltmesi ve 1 regresyon üretti, ama regresyonlar genelde tam çökme değil, yanlış davranış düzeyinde yani daha düşük ciddiyetteydi
      Buna özellik tabanlı test de eklenince ortalama 2-4 saat sürüyordu ve her zaman en az bir bug ortaya çıkarıyordu. Kod özellik tabanlı teste uygunsa yapılmalı
      DeepSeek V4 Flash gibi ucuz bir modelle test kapsamını artırırken çöp testler üretilmemesine dikkat edince günde yaklaşık 2-3 mantık bug'ı düzelttim ve hiç çökme olmadı. Yine de test paketi zar zor bakım yapılabilir durumda
      Bir junior'ın Sonnet ve Opus 4.5, 4.6 ailesiyle kabaca test üretmesine izin verdiğimde modeller sadece “mevcut davranışı belgeleme” türünde testler yazdı; bu yüzden düzeltme etkisi küçüktü, test paketi de bakım yapılamaz hale geldiği için atılması gerekti
      Model tabanlı test bug yakalamada çok iyi, ama kurulumu karmaşık ve modeli yüzeydeki işlevlerde döngüye sokmadan köşelere doğru kazmaya yönlendirmek çok uğraştırıcı. Profil tabanlı model güdümlü bir fuzzer gibi bir şey ilginç olabilir
      Özetle tip denetleyicileri ölümcül hataları ve çeşitli karışıklıkları iyi yakalıyor, özellik tabanlı testler harika. Genel testler ise düzenli olarak karşılık almak için çok fazla disiplin gerektiriyor
    • Ben şahsen öyle olduğunu düşünüyorum. Kullandığım JavaScript'te null pointer bugları, TypeScript'e geçtikten sonra neredeyse önemsiz hale geldi; ekip arkadaşlarımda da durum benzerdi
  • Burada TypeScript'i iyi bir tip sistemiyle aynı sepete koymaya itiraz etmekte en çok zorlanıyorum

    • Evet. TypeScript sound değil ve özellikle await üzerinden tip daraltma biçimi beni birkaç kez vurdu. Yine de durumu dramatik biçimde iyileştirdiği doğru
      Dürüst olmak gerekirse yapısal tiplemeyi de sonunda benimsedim ve bunun gelecekteki dil tasarımını olumlu etkileyeceğini düşünüyorum
  • Bu iddia çok ikna edici değil. Cebirsel veri tipleri ve tip çıkarımı olan makul programlama dilleri 90'ların ortasından beri vardı
    Java ve C++'ın tip sistemleri çok zayıftı ama SML, OCaml ve Haskell zaten vardı ve bugünküne oldukça benzer hissettiriyordu. İnsanlar o dilleri kullanmadıysa bu kültür, benimsenme ve açıkça ifade edilmemiş gereksinimlerle ilgili bir sorundur; bunu sadece “kullanılabilir tip sistemleri yeterince iyi değildi” diye açıklayamayız
    Ya da kastedilen “o dönemin popüler dillerinin tip sistemleri kötüydü, bugünün popüler dillerinin tip sistemleri daha iyi, bu yüzden tip sistemleri daha popüler oldu” ise bu kulağa döngüsel bir argüman gibi geliyor
    Tip sistemleriyle birlikte tasarlanmış diller ile başta tipsiz tasarlanıp sonradan üzerine tip sistemi eklenmiş diller arasında da çok fazla nüans var

  • Aslen dinamik tipleri tercih eden biri olarak da bu yazının oldukça adil olduğunu düşünüyorum. Bugünlerde C# ile çalışıyorum, hobi olarak Lisp kullanıyorum ve eskiden Python da kullandım
    Java 5 kullanmak zorunda kaldığımda çoğu zaman kütüphane geliştiricilerinin kötü kararları yüzünden tip sistemiyle sürekli kavga ediyordum. 2010 civarında C#'a geçtikten sonra tip sistemi aktif olarak zararlı değildi ama çoğunlukla tekrarlıydı ve Python'da en yaygın tip karışıklığı olan null pointer exception'ı da engellemiyordu
    C#'ın tip sistemi gerçekten yardımcı olmaya ancak 2020 civarında nullable olmayan referans tipleri gelince başladı. Bu yıl yerel union tipleri de geliyor, ama exhaustiveness zorlayan union tipi kütüphaneleri en azından 2016'dan beri mümkündü ve ben kullanmaya 2020'de başladım
    Modanın hâlâ rol oynadığını düşünüyorum, ama bunun bir kısmı kötü değil. Daha ifade gücü yüksek tip sistemlerine sahip moda diller, para kazanmak için kullandığımız sıradan dillere de iyileştirmeler getirdi

  • Haskell ve onun tip sistemi aslında 2000’lerde de vardı. Bugünkü kadar yaygın kullanılmıyordu ama kesinlikle mevcuttu; bu yüzden bu iddianın o kısmı düzeltmesi gerekiyor
    Bana göre TypeScript, ana akım dil kullanıcılarını daha iyi bir tip sistemine alıştıran en büyük etkenlerden biriydi. Kalitesi ve Microsoft desteğinin yanı sıra JavaScript’e uygulanabilmesi de büyük avantajdı ve JavaScript’in tipe ihtiyacı Python’dan daha acildi. Bunun nedeni “Undefined is not a function.” ve “The good parts.”

    • Modern JavaScript sürümlerine uyarlanmış bir “good parts” kitabının, kısa ve öz kalmayı başararak çıkmasını isterdim
      “Real World Haskell” 2008’de çıktı ve amacı Haskell’i ana akım programcılara daha çekici göstermekti. İyi haberi yaymaya ne kadar yardımcı olduğunu bilmiyorum
      Java dünyasında Scala 2004’te etkileyici tipler getirdi, .NET tarafında ise F# 2005’te çıktı. Scala belki de Twitter gibi dikkat çeken kullanıcıları en çok kazanan dildi, ama TypeScript gibi o platformun kullanıcılarının büyük bir kısmını içine alabilecek bir konumda değildi; ayrıca Rust veya Go gibi başka dillerin kullanıcılarını kitlesel biçimde çekecek kadar da cazip değildi
    • Yazı bu meseleyi zaten ele alıyor. 90’lar ve 2000’lerin başında popüler olan erken dönem Java ya da C++98 gibi zayıf statik tip sistemlerini kâğıt küreğe benzetmişti
      Hemen sonraki paragrafta Haskell’den “modern tip sistemi” olarak söz ediyor, ama 90’ların sonu ile 2000’lerin başında Haskell deneyimi olanların oranı, kişisel olarak kurcalamış olanlar dahil edilse bile, fiilen %0’a yakındı. Yazı, o dönemde çoğu geliştiricinin statik tipli dilleri nasıl deneyimlediğini ve neden çoğunluğun statik tipli dillerden topluca kaçındığını anlatıyor
    • Bence Haskell ve OCaml bir ölçüde araç ekosisteminin zayıflığı yüzünden zorlanıyor. Dilin kendisi harika ama araç tarafındaki sayısız küçük pürüz yüzünden benimsenme kaybediyor
      Örneğin OCaml’da dune kullanmak için opam dosyasını, dune dosyasını, ocaml module sözdizimini ve ocaml sözdizimini anlamanız gerekiyor. Haskell’deki isteğe bağlı derleyici eklentileri de aynı derecede ürkütücü geliyor
      Bu, cargo tarafında yalnızca toml ve Rust bilmenin yeterli olmasıyla tezat oluşturuyor