3 puan yazan GN⁺ 2024-11-27 | 2 yorum | WhatsApp'ta paylaş
  • Go eleştirilerine karşı tekrar eden “büyük şirketler de kullanıyor”, “iyi yanları da var”, “doğruluk maliyetlidir” gibi itirazlar, dil tasarımı kusurlarının uzun vadeli maliyet olarak birikmesi sorununu bulanıklaştırabilir
  • Go; asenkron runtime, GC, paket yönetimi, refactoring ve çapraz derleme araçlarında güçlüdür; ancak özel toolchain’i, build sistemini, çağrı konvansiyonunu, tek GC’yi ve ekosistemi de birlikte kabul etmeyi gerektirir
  • sum type eksikliği, değiştirilebilirliği kontrol etme yetersizliği, zero value ve nil slice/map/channel’ların farklı davranışları nedeniyle derleyici birçok invariant’ı koruyamaz
  • cgo olmadan diğer diller ve araçlarla entegrasyon zordur; cgo kullanınca da GC ve pointer kuralları, runtime’ı dahil etme ve büyük statik kütüphane yükü ortaya çıkar; bu yüzden ağ sınırı en gerçekçi entegrasyon noktası hâline gelir
  • “Prototipi Go ile yapar, sonra yeniden yazarız” beklentisi pratikte yeniden yazımdan kaçınma, mevcut Go koduyla bağlanma, linter/dokümantasyon/manuel doğrulama yükleri nedeniyle operasyon maliyetini artırabilir

Go eleştirilerinde tekrar eden savunma mantığı

  • 2020’deki I want off Mr Golang’s Wild Ride yazısından sonra Go eleştirileri etrafındaki tepkiler sürekli tekrarlandı
    • Windows örneğinin Go’nun iyi olduğu alan olmadığı tepkisi
    • Go’nun iyi yanlarından bahsetmediği tepkisi
    • Go’nun seçtiği ödünleri anlamadığı tepkisi
    • Büyük şirketler Go kullandığı için çok kötü olamayacağı tepkisi
    • Sorunu “doğru” modellemenin maliyeti yüksek olduğundan doğruluk tartışmasının anlamsız olduğu tepkisi
    • Rust’ın da eksileri olduğu için Go eleştirisinin geçersiz olduğu tepkisi
  • Asıl mesele Go’nun avantajları olup olmadığı değil, Go kullanmaya devam etmek için tekrarlanan savunma mantığının gerçek maliyeti gizleyip gizlemediğidir

Önce eleştirmenin yetkinliğine saldırma yöntemi

  • Duymak istemediğiniz bir geri bildirim geldiğinde, bunu söyleyen kişinin yetersiz ya da gizli bir motivasyona sahip olduğunu varsayarsanız içeriği incelemenize gerek kalmaz
  • Bir sorunu fark etmek için mutlaka yüksek uzmanlık gerekmez; kıdemli geliştiriciler alıştıkları rahatsızlıkları aksine görmezden gelebilir
  • Junior geliştiriciler henüz tuhaflıklara alışmadıkları için rahatsızlığı daha hızlı hissedip soru sorabilir
  • Geri bildirimin değeri, kimin söylediğinden çok gerçekten bir sorun olup olmadığına göre değerlendirilmelidir

“Başka şirketler de kullanıyor” gerekçesinin sınırları

  • Teknoloji seçiminde başka şirketlerin ne kullandığına bakmak keşif için yararlıdır; ama benimseme gerekçesi olarak yeterli değildir
  • Şirket teknoloji blogları genellikle benimseme maliyetini tam olarak ortaya koymakta zorlanır
    • Çoğu zaman karar zaten verildikten sonra yazılırlar
    • Şirket imajını iyi göstermek ve işe alıma yardımcı olmak gibi amaçları vardır
    • Güçlü teknik eleştiriler çoğunlukla şirketlerden değil bireylerden gelir
  • Tailscale’in Go kullanımı, maliyeti bilen ve kaldırabilecek bir Go uzmanları ekibinin örneğine daha yakındır
  • netaddr.IPte görülen acının nedeni Go’nun çeşitli kısıtlarıyla iç içedir
    • Go’da sum type olmadığı için “IPv4 veya IPv6” tipini ifade etmek hantaldır
    • slice, 64-bit makinelerde 24 bayt maliyeti olan genel amaçlı bir veri yapısı olarak kullanılır
    • Operatör overload’u olmadığı için a == b ile a.equals(b) gibi ayrımlar ortaya çıkar
    • Immutable veri desteklenmediği için kopya geçirmek ve içerideki değişikliklere dikkat etmek gerekir
    • Opak bir newtype oluşturmak zor olduğundan ayrı paket ve interface üzerinden dolanma gerekir
  • Tailscale gibi ekipler Go’nun iç işleyişini ve sınır durumlarını derinlemesine ele alabilir; ancak her kurum Google veya Tailscale gibi Go uzmanlarına ve mühendislik maliyetini karşılayacak imkâna sahip değildir

Go’nun gerçekten iyi yaptığı şeyler

  • Go oldukça iyi bir asenkron runtime, güçlü görüşlere sahip varsayılanlar, iki ayar düğmesi olan modern bir GC ve iyi bir araç zinciri sunar
  • Asenkron runtime dilin merkezinde olduğu için Rust geliştiricilerinin imrenebileceği araçlar da vardır
    • Çalışan tüm goroutine’lerin backtrace’ini kolayca dump edebilirsiniz
    • Deadlock tespiti mümkündür
    • Kendi profiler’ı vardır
    • Function coloring’i daha az düşünmenizi sağlar
  • Paket yönetimi, refactoring ve çapraz derleme araçları; C ekosistemindeki pkg-config, autotools ve CMake’e kıyasla başta bir iyileşme gibi gelir
  • Ancak Go’nun kullanışlı runtime’ını tek başına seçip kullanmış olmazsınız
    • Özel toolchain
    • Build sistemi
    • Çağrı konvansiyonu
    • Tek GC
    • Dahil edilmiş standart bileşenler ve ekosistem
    • Tesadüfen şekillenmiş dil tasarımı da birlikte benimsenir

Tip sistemi ve dil tasarımındaki boşluklar

  • Go; TCP, HTTP, TLS, HTTP/2, DNS ve web servisleri uygulamaya yönelik runtime’ı merkeze alır ve Java/C/C++/Python öğrenmiş Google geliştiricilerine tanıdık gelecek bir biçim alır
  • C gibi hata işlemeyi kendi başına fazla ele almaz; çok sayıda değiştirilebilir durumu geliştiricinin if ve else ile doğrudan yönetmesi gerekir
  • Java gibi değer ve referans ayrımını bulanıklaştırır; yalnızca çağrı noktasına bakarak değerin değişip değişmeyeceğini anlamak zordur
    • Method receiver’ın A mı yoksa *A mı olduğuna bağlı olarak main içindeki yerel değişken a değişebilir ya da değişmeyebilir
  • Değiştirilebilirlik ve değişmezliği tiplerle net biçimde sınırlamak zor olduğundan, referans geçirilirken iç değerlerin değişmesi veya uzun süre tutulup serbest bırakılmaması riski vardır
  • Go aşağıdaki hata gruplarını yeterince engelleyemez
    • Mutex’in yanlışlıkla kopyalanıp etkisizleştirilmesi
    • Struct alanlarının initialize edilmemesi ve zero value alması
    • Yanlış nil, zero veya empty string’in sistemin derinlerine yayılması

zero value ve “dikkat edersen yeter” yaklaşımının sınırları

  • Bir struct’a yeni alan ekleyip fiilen fonksiyon girdisinin biçimini değiştirseniz bile, composite literal’da yeni alan atlanırsa derleyici bunu engellemez
    • Örnekte Paramsa b int32 eklenmiştir; ancak çağıran taraf yalnızca a: 47 geçirirse b=0 ile çalışır
    • Buna karşılık fonksiyon argümanını doğrudan eklerseniz argüman sayısı yetersiz olduğundan derleme hatası oluşur
  • Go’nun ilkelerinden biri zero value’nun kullanışlı olmasıdır; ancak gerçek anlamı tipe göre değişir
    • nil slice üzerinde len çağrılırsa sonuç 0’dır ve boş slice gibi davranır
    • nil map’e değer koyarsanız panic: assignment to entry in nil map oluşur
  • Channel’lar için de ayrı kurallar vardır
    • nil channel’a send yaparsanız sonsuza kadar block olur
    • nil channel’dan receive yaparsanız sonsuza kadar block olur
    • Kapalı channel’a send yaparsanız panic oluşur
    • Kapalı channel’dan receive yaparsanız zero value hemen döner
  • Go’da sum type olmadığından “yalnızca bilinen seçeneklerden birine izin veren” girdiyi tip olarak ifade etmek zordur; C’deki gibi “sadece dikkatli ol” yaklaşımına yakındır
  • Tüm sorunları engelleyemiyoruz diye bazı sorunları da engellemeye gerek olmadığı tutumu yanlış bir ikilemdir; tip sisteminin yardımcı olabileceği sorunlar bile manuel dikkate bırakılır

Rust karşılaştırması “kusursuz alternatif” tartışması değildir

  • Buradaki duruş Rust’ın kusursuz olduğu değildir; Go ve Rust farklı biçimlerde başarılı örnekler olarak görülebilir
    • Go’nun başarısı büyük ölçüde dahil edilmiş bileşenlere ve güçlü görüşlere sahip varsayılanlara dayanır
    • Rust’ın başarısı büyük ölçüde kademeli benimsemeye ve diğer dillerle entegrasyon kolaylığına dayanır
  • Gerçek Rust benimseme örnekleri, komple değiştirmeden çok kademeli port etmeye yakındır
    • Firefox, büyük bir C++ kod tabanı içinde birkaç temel Rust bileşeni içerir
    • Android, Bluetooth stack’ini Rust ile yeniden uyguladı
    • Rust kriptografi kodu Python’a girdi; Rust HTTP kodu curl’ün çeşitli backend’lerinden biri oldu
    • Linux kernel Rust patch’i tekrar tekrar iyileştiriliyor
  • Rust kullanıcıları da build süreleri, dil özelliği eksiklikleri ve diğer dezavantajlar hakkında aktif biçimde konuşur
  • Tartışma Go ile Rust’tan birini koşulsuz seçmek değil; değiştirilebilirlik, yaşam süresi ve soyutlamaları tiplerle ifade edebilen araçların hangi sorunları azalttığıdır
  • Rust’ta da her durumu katı biçimde modellemeyebilirsiniz
    • Örneğin düşük seviyeli ls benzeri bir araç değilse yalnızca UTF-8 path’lerle çalışmak için camino kullanmayı seçebilirsiniz
    • Hata işlemede yalnızca birkaç önemli variant’ı listeleyip geri kalanını Other, Internal, Unknown olarak bırakabilirsiniz
    • Option<T> için unwrap() çağırmak, değerin var olduğunu açıkça iddia etme biçimidir

Go diğer ekosistemlerden kopuk bir adaya daha yakındır

  • cgo kullanmazsanız Go; alışılmış assembly, linker, debugger, bellek denetleyicileri ve çağrı konvansiyonlarından uzaktır
  • Go, C/C++’tan çok closed-world bir dile yakındır; Node.js, Python ve Ruby’ye kıyasla FFI’ye daha düşmancadır
  • Bu farkın avantajları da vardır
    • TLS ve HTTP stack’inin içini iş mantığıyla aynı şekilde profiler’da görebilirsiniz
    • Dinamik dillerde stack trace’in OpenSSL’de durmasıyla tezat oluşturur
    • Runtime non-blocking I/O ve scheduling’i yönetebilir
  • Ancak mevcut birçok aracı ve kurumsal bilgiyi olduğu gibi kullanmak zordur; Go ile başka dilleri entegre etmek de zahmetlidir
  • Go entegrasyon yöntemlerinin her birinin maliyeti vardır
    • Go’dan C çağırırsanız FFI sınırı maliyetinin yanında GC’yi bozmamak için manuel descriptor takibi gerekir
    • Başka bir dilden Go çağırırsanız GC dahil tüm Go runtime’ını birlikte koymanız gerekir; büyük statik kütüphane ve operasyon yükü doğar
  • Go ile temas eden en iyi sınır ağ sınırına yakındır
    • REST-ish HTTP/1, JSON-RPC ve gRPC gibi TCP üzerinden RPC yaklaşımları, gecikme maliyetini kaldırabiliyorsanız görece daha az acı verir
    • Yine de iki tarafta da invariant’ları korumak gerekir; Go tarafında doğrulama paketleri düzenli kullanılmazsa derleyici bunu garanti etmez

Prototip için Go beklentisinin tuzağı

  • Go’nun öğrenmesi ve işe alımı kolay olduğu için önce prototip yapıp, işler zorlaşınca daha sonra yeniden yazma veya uzman getirme düşüncesi vardır
  • Ancak “atılacak kod” pratikte neredeyse yoktur
    • Yeniden yazmak zaman alır
    • Sorunsuz geçiş koordinasyonu zordur
    • Ayrıntılar kaybolabilir
    • Yeni özellik geliştirme durur
    • İnsanları yeni teknolojiye göre yeniden eğitmek gerekir
  • Go bileşenleri arttıkça mevcut Go koduyla etkileşim kurmak için Go seçmeye devam etme nedenleri de artar
  • Linter’lar bir ölçüde yardımcı olur; ancak sorunu baştan ciddiye alan bir dilin derleyicisi kadarını yapamaz ve geliştirme hızını da düşürür
  • Dilde bulunmayan karmaşıklık kod tabanına taşınır
    • Tiplerle ifade edilmeyen invariant’lar kodla doğrudan yazılmak zorundadır
    • Yalnızca fonksiyon imzasından verinin değiştirilip değiştirilmeyeceğini, saklanıp saklanmayacağını, zero value’ya izin verilip verilmediğini, goroutine başlatılıp başlatılmadığını, nil channel olasılığını veya interface{}e gerçekte hangi tiplerin geçirilebileceğini anlamak zordur
    • Dokümantasyona bağımlı olunur; dokümantasyonun hem güncelleme hem de güncellenmeme maliyeti yüksektir

Sonuçta özetlenen “yalanlar”

  • Go kullanmaya devam etmek için kendimize söylediklerimiz şöyle özetlenebilir
    • Başkaları kullandığına göre bizim için de iyi olacaktır
    • Endişelerini dile getiren kişi elitist ya da kaba biridir
    • Cazip asenkron runtime ve GC diğer tüm eksileri telafi eder
    • Her bir dil tasarımı kusuru tek başına da, birleştiğinde de sorun değildir
    • “Dikkatli olmak”, linter’lar ve daha fazla reviewer ile üstesinden gelinebilir
    • Yazması kolay olduğu için production yazılım geliştirmek de kolaydır
    • Dil basit olduğu için geri kalan her şey de basittir
    • Azıcık kullanırız ya da sadece başta kullanırız; kolayca çıkabiliriz
    • Daha sonra istediğimiz zaman yeniden yazabiliriz
  • Seçilen araç karmaşıklığı ortadan kaldıramıyorsa, bu karmaşıklık başka geliştiricilere, operatörlere ve müşterilere taşınır
  • nil değerlerin girmemesi gereken yerlere girip production’da gece uykunuzdan uyandırdığı durumlar, Billion Dollar Mistake’in tekrarına dönüşür

2 yorum

 
tsboard 2024-11-28

Go diliyle çok kısa ama yoğun bir süre geçirmiş bir amatörün yazı bırakması ne kadar uygun emin değilim ama... Go dilinin artıları ve eksileri gerçekten çok net; bu yüzden onu seçenlerin de kaçınanların da belli nedenleri var gibi görünüyor. Bana kalırsa bunu Rust ile değil, Kotlin(Java) ile karşılaştırmak daha doğru.

Go'nun goroutine'leri gerçekten harika, ama sihir değil. Özellikle backend tarafında sadece tek bir MySQL kullanan küçük projelerde bu eşzamanlılık meselesini yönetmek gerçekten zor. JS/TS runtime'larında çok da dert etmediğiniz MySQL kaynak tükenmesi ya da pool yönetimi, düşündüğünüzden daha zor olabiliyor. Sonuçta bu durumda darboğaz DB olduğu için Go dilinin eşzamanlılık avantajı kısmen soluyor. (JS/TS runtime'larının asenkron I/O'su ya da event loop'u hatta daha uygun olabilir.) Bunu hey gibi bir araçla -c 100 verip denediğinizde hemen anlayabilirsiniz.

Ayrıca iyi bir GC var diye, nesneleri gelişigüzel sadece pointer geçirerek kullanıp temizliği tamamen akışına bırakamazsınız. Her şeyde olduğu gibi burada da trade-off var; Go dilinde de mümkünse küçük nesneleri doğrudan değer kopyasıyla aktarmak ve fonksiyon biter bitmez işlerinin kapanmasını sağlamak daha iyi. Belki eski düşünce tarzına saplanmış olabilirim ama, C/C++ dillerindeki verimlilik bakışıyla pointer'lara kolayca yaklaşmamak gerekiyormuş.

Fonksiyondan error dönerken neredeyse her seferinde geri döndürmek ve onu her seferinde if err != nil {} ile kontrol etmek gerçekten yorucu, ama bu bir avantaj. Çünkü maliyeti try catch'ten daha düşük. Ayrıca finally {} benzeri bir rol üstlenen defer anahtar sözcüğü de harika. Kaynağın ne zaman serbest bırakılacağını düşünmek zorunda kalmamak güzel. Sadece standart kütüphane ile bile gayet iyi bir backend sunucu yapısının hemen kurulabilmesi de güzel (1.23 ve üzeri). Hepsinden önemlisi, hedef OS'e göre build edildiğinde başka bir runtime'a ya da ön kurulumlara ihtiyaç duymaması bence en büyük artısı.

Go dilini uzun süre kullanmadım ama fazla kişisel bir görüşü uzatıyormuşum gibi hissettiğim için burada keseyim. haha Ben Go dilini de seviyorum, diğer dilleri de!

 
GN⁺ 2024-11-27
Hacker News yorumları
  • Bu yazı Go’nun eksilerini büyük ölçüde iyi yakalıyor, ama açık hata işlemenin bunlardan biri olduğunu düşünmüyorum.
    İstisna işlemeyi, çok kolay bozulabilen bir “sihir” katmanı eklediği için hiç sevmedim; teknik olarak kusursuz bir argüman olmasa da onlarca yıllık deneyimim, hataların tam ortaya çıktığı noktada ele alınmasını tercih ettiriyor.
    Rust’ın bunu daha zarif yaptığını söyleyebiliriz ve kişisel projelerde Rust’ı daha çok seviyorum; ama farklı yetkinlik seviyelerinde geliştiricilerin girip çıktığı büyük projelerde Go’nun felsefesini modern hata işleme yaklaşımları içinde epey makul buluyorum.
    Benim bölgemde Go, sadeliği sayesinde diğer “yeni” dillere kıyasla çok daha fazla benimseniyor. En iyi dil değil, ama kendinize zarar vermenizi engelleyen yerleşik çok sayıda sağduyu içerdiği için genel amaçlı bir dil olarak çoğu zaman en iyi seçenek oluyor.

    • Go’nun hata işlemesinin çeşitli dezavantajları var. Yazar Rust tarafına epey yaslandığına göre alternatif istisnalar değil, Result sum type.
      Stack trace yok ve hataları sarmalamak gerekiyor; bu yüzden yalnızca benzersiz hata mesajları değil, her çağrı noktası için benzersiz sarmalama mesajları da üretmeniz gerekiyor ki mesajlarda grep yapıp stack trace benzeri bir şeyi tahmin edebilesiniz.
      “Dönüş tuple’ı”, yalnızca hatalar yüzünden var olan tuhaf bir düzenek; dilin başka yerlerinde tuple bile kullanamıyorsunuz. Garip değişken başlatma kuralları yüzünden bir gün mutlaka yanlış err değişkenini kullanıyorsunuz.
      Go’da enum olmalıydı ya da yalnızca hatalara özel tuhaf bir “dönüş tuple’ı” yerine Rust’taki ? gibi daha iyi bir söz dizimsel şeker eklenmeliydi. Mevcut yöntem sıkıcı ve hataya açık.
      Go’nun inatçı bir duruşu var, ama bu çok sık, dili eleştiriden korumaya çalışan bir inat gibi görünüyor. Ne yazık ki bir programlama dilinin popülerlik kazanmasında pazarlama, yani yalanlar da önemli; bu yüzden işe yarıyor.
    • 30 yılı aşkın süredir programlama yapıyorum ve C#’ı da neredeyse 10 yıl kullandım; ama istisnaların programlama tarihindeki en kötü fikirlerden biri olduğunu düşünüyorum.
      İstisnalar, herhangi bir kütüphanenin koduma fırlatabileceği berbat bir gotodur ve neredeyse hiç düzgün işlenmez. Bir istisna “işlendikten” sonra bile uygulama genellikle bilinmeyen bir duruma düşer ve hakkında akıl yürütülemez hale gelir.
      Go hatalarını junior mühendisler bile çoğunlukla kolayca debug edebilirken, Java istisnalarının gerçek nedenini deneyimli principal’lar bile anlamakta zorlanır.
    • Go’nun hata işlemesini övenlerin istisnasız olarak yalnızca istisnalarla karşılaştırdığını ve sanki istisnalar tek alternatifmiş gibi konuştuğunu gördüm.
      Buna karşılık Maybe, Option, Result gibi sum type’lara aşina olup da Go’nun yaklaşımını az da olsa iyi bulan birini henüz görmedim.
    • Bu hata işleme kısmı neredeyse saf bir din meselesi ve Go’nun en temel ilkelerinden biri olan “kod, yazması kolay olmaktan çok okuması kolay olmalı” ilkesine de ters düşüyor.
      Belirli bir metodun mantığını okumaya çalışırken satırların %75’i hata gürültüsü, yalnızca %25’i gerçek davranışı anlamak için gerekliyse bunu okumak zordur.
      Bir kod tabanına ilk baktığımda, hata uç durumlarından önce neyi başarmaya çalıştığını bilmek isterim; sonra bunun doğru olduğunun nasıl güvence altına alındığına bakarım.
      Bu açıdan Go’nun hata işlemesi büyük ölçüde başarısız. Açık hata işlemenin kötü olduğu değil; sorun, başarı yolu ile hata işlemeyi satır satır birbirine karıştırma ısrarı. Özel bir hata işleme bölümünde de açık biçimde işleyebilirsiniz.
    • Açık hata işlemenin aşırı olduğu iddiasına katılmıyorum.
      Katıldığım nokta, kodun üretebileceği tüm olasılıkları düşünmeye zorlaması. Yalnız bu, diğer dillerden çok C’ye yakın bir soru.
      Kodu soyutlarken hatayı hemen ele almanız gerekmeyebilir ya da çağrı yığınının daha aşağılarında ele almak isteyebilirsiniz.
      Dilin belirli bir yöntemi dayatması için okunabilirlikten epey feragat edilmiş oluyor.
  • Rust ve Go çok farklı; insanlar sanki şu anda mevcut olmayan bir orta nokta istiyor gibi görünüyor
    Çöp toplaması olan, nispeten basit, statik bağlı ikili dosyaya derlenen; ama Rust’a benzer bir tip sistemi ve remainder type gibi şeyleri olan bir dilden söz ediyorum
    Sözdizimi açısından Gleam ve Kotlin bir ölçüde buna yakın, ama tam olarak değil. Rust’ı seviyorum; ancak bir şeyler inşa etme yeteneği olsa da bilgisayar bilimi mezunu olmayan ve programcı olarak çalışmayan birçok kişi için fazla karmaşık olduğunu düşünüyorum
    Dili yalnızca ara sıra kullanıyorsanız vtable’ın ne olduğunu, bir değerin ne zaman ve nasıl serbest bırakıldığını hatırlamazsınız. “Mükemmel dil” yok, ama Go ve Rust’ın ikisi de harika şeyler getirdi; umarım biri ikisinden ilham alıp yaygın kullanılabilecek basit bir dil yapar

    • Kotlin bir orta nokta olarak ilginç, ama çoğu işte Go’dan çok daha düşük üretkenlik sağladığını ve Rust’ı çıkaracağınız işlere de uygun olmadığını düşünüyorum
      Gerçekte Kotlin oldukça karmaşık; akıllıca davranmaya çalışırken zaman harcıyorsunuz. Bir işi yapmanın 1000 yolu var; operatör aşırı yükleme, proxy’ler, property’ler, companion object’ler, exception’lar ve result type’ların hepsi mevcut
      Gradle kullandığınızı varsayarsak, derleme sistemi go builde alışkın biri için işkenceye yakın
      Coroutine API’si Goroutine’lerden aynı anda hem daha karmaşık hem de daha kısıtlayıcı hissettiriyor. Daha yapısal, ama daha az esnek ve kullanmak için daha fazla çaba gerektiriyor
      Erişim denetimi de tuhaf. Bir tipi pakete özel yapmanın yolu yok; ya dosyaya özel ya da tüm modüle açık. Bu yüzden istemeden API yüzeyi büyüyor ya da karmaşıklığı birden fazla dosyaya bölemiyorsunuz
      Kotlin/Native ve Kotlin/JVM fiilen farklı şeyler. Kotlin/JVM olgun, ama JVM üzerinde çalıştığı için Rust’ı tercih edeceğiniz kullanım alanlarının bir kısmı ortadan kalkıyor
      Kotlin/Native ekosistemi çok zayıf, belgeleri de yetersiz. Issue tracker’da korkutucu hatalar da var
      Kotlin/Native, yalnızca kaynak koddan oluşan kütüphane dağıtımını bile yapamadığı için tüm işletim sistemleri ve mimariler için ikili dosya derleyen karmaşık bir CI gerekiyor. Ya da kütüphaneyi hiç dağıtmıyorsunuz; bu da zayıf ekosistemi daha da kötüleştiriyor gibi
    • Kişisel olarak, insanların Go’da olsa iyi olur dediği Rust özelliklerinin çoğunun hâlâ Go’nun “kavramı” içine sığabileceğini düşünüyorum
      Generic’lerin eklenmesi gibi, sadece üç şey eklemek yeterli: hatalar için generic bir container olan Result, daha iyi nil işleme için Optional ve Elvis operatörü gibi küçük bir sözdizimi şekeri
      Go’nun başarısını neredeyse tek başına açıklayan büyük avantaj, dev bir şirket tarafından geliştirilmesi ve bizzat kullanılması; bu sayede harika araçlar ve açık kaynak kütüphaneler üretme kapasitesine sahip olmasıydı. Halihazırda kullanılıyor olması ve kütüphanelerinin bulunması, bir dilin başarısındaki en büyük belirleyici gibi görünüyor
    • Bu konudaki düşüncem, başka bir deyişle şöyle: JavaScript’ten başlamak
      Temel sözdizimi çok doğrudan, benimsenmesi zaten muazzam, ekosistemi büyük, çalışma zamanı sürekli iyileşiyor ve WASM’e derlenebiliyor
      Buna, tuhaf kısımları —örneğin aşırı yeniden tanımlama esnekliği, global scope’un kötüye kullanımı, sayılarla ilgili gariplikler— çıkarıp tipler, sum type/product type, Result, Maybe, decimal vb. ekliyorsunuz
      Ayrıca her şeyin ifade olduğu bir tarz, pattern matching, currying gibi fonksiyonel özellikler ve kapsamlı bir standart kütüphane koyarsanız, birçok insanın istediğine en yakın dil ortaya çıkabilir
      Geliştirici araçlarında görmek istediğim bir başka büyük ilerleme de HTML’i elden geçirip doğru düzgün üst seviye kontrolleri yerleşik hale getirmek ve inline CSS ile kolayca stillendirilebilir kılmak. Böylece istemcide gereken JS miktarı azalır
      Bu iki şeyin web ile ilgili geliştirmelerde programlama üretkenliğini ciddi biçimde artıracağını düşünüyorum
    • Yazarıyım; Gleam hangi açıdan o noktaya ulaşamıyor? Ben de böyle bir orta nokta aradığım için Gleam’i epey merakla takip ediyorum
    • C# ve F# açık ara en yakın seçenekler. Diğer alternatiflerde bu ikisiyle boy ölçüşecek kadar iyi bir tip sistemi ya da araçlar yok
      dotnet publish -p:PublishAot=true ile statik native binary olarak derleyebilirsiniz. F#’ta print* yerine Console.* metotlarını kullanmak gerekiyor; çünkü print, %A biçim belirtecinin yapısal çıktısı nedeniyle içinde sınırlandırılmamış reflection barındırıyor, bu da binary boyutunu olumsuz etkiliyor ve derleyici şikâyet ediyor
      Özellikle F#, “daha kolay ve iş odaklı bir Rust alternatifi” olarak önerilebilir. Expression-oriented bir dil; discriminated union’lar, eksiksiz HM type inference ve gradual typing iyi uyum sağlıyor. Veri analizi ve domain modeling de çok rahat
      Sistem programlama için C# bir seçenek haline geliyor. Harika eşzamanlılık temel öğeleri, hızlı ve bazen neredeyse sıfır maliyetli native interop, Go’dan daha küçük native binary’ler ve taşınabilir SIMD dahil birçok düşük seviye API sunuyor
      Go bu tür işlere çoğu zaman pek uymuyor ya da dolambaçsız şekilde hiç yapamıyor. .NET bu alandaki oyun dışı toplulukta popülerlik kazanıyor ve yüksek performanslı çok sayıda kütüphane de ortaya çıkıyor. Ayrıca kardeş yorumda önerilen niş dillerin aksine, devasa mevcut ekosistemden yararlandığı için tüm temel işleri kendiniz yapmak zorunda kalmıyorsunuz
  • Go: “Ben basit bir dilim!”
    Kullanıcı Go’yu bir süre kullanır
    Kullanıcı: “Senden nefret ediyorum, sen basit bir dilsin!”
    Ben 50’li yaşlarımda ya da üstünde olduğumdan mıdır bilmem, basit dilleri seviyorum
    Bu “eleştiri” pek dengeli görünmüyor; teknolojide her şey bir ödünleşimdir ve dengesiz yargıların zayıf olduğunu düşünüyorum
    Elbette benim vardığım sonuç farklı: https://www.inkmi.com/blog/why-we-chose-go-over-rust-for-our...

    • Go eleştirilerine sıkça yapıştırılan bir çarpıtma bu. “Sen basitliği anlamıyorsun, Java beyin kurdu kapmışsın” gibi bir şey
      Yazıda dilin can sıkıcı tutarsızlıklarına işaret eden çok sayıda örnek var ve bunlar basitliğin zıddı
      Rob Pike’ın Go sunumunu seviyorum; bazı kısımları benim için ufuk açıcıydı. Ama pratikte gördüğüm Go’nun, Go hayranlarının soyut olarak anlattığı Go’ya çok daha yakın olmasını isterdim
    • Go’nun “basit” bir dil olduğu söyleminin ortadan kalkmasını isterim
      Göründüğünün aksine, Go kullanmaya başlayınca kısa sürede basit olmadığı ortaya çıkıyor. Çok sayıda gizli karmaşıklık ve tuzak var. Örn: https://archive.ph/WcyF4
      Yine de kullanışlı bir dil ve epey kullanılıyor, ama “basit” değil
    • Go’nun sorunu, kullanıcılar için basit bir dil olarak değil, bakımını yapanların kolayca uygulayabileceği bir dil olarak tasarlanmış olması
      Basit bir dilin yüksek tutarlılığa sahip olması gerektiğini düşünüyorum. Kurallar az olmalı ama her yerde genel ve tutarlı olmalı. Oysa Go’da her yerde tuhaflıklar, tutarsızlıklar ve dolambaçlı çözümler var
      Buna iyi bir örnek tipin atlanması. Dizi, slice ve map bildirimlerinde mümkün, ama struct’larda değil. Struct’larda da izin verilse okunabilirlik açısından birçok avantajı olurdu; anonim struct argümanları üzerinden adlandırılmış parametreler de mümkün hale gelir, bu da bugün kullanılan çirkin dolambaçlı çözümlerden çok daha iyi bir tasarım sağlayabilirdi
    • Scheme basit bir dildir, ama Go karmaşıklığı en kötü anda patlayana kadar gizler
      Elbette Go’nun makul alternatiflerinin çoğu da bu açıdan daha kötüdür. Python, Ruby, JS gibi şeyler
    • Go yalnızca basit işler yaparken “basit”tir. Kendi KV deposunu ya da veritabanını yazmaya çalışırsan, biraz daha modern dil özelliklerine çok çabuk ihtiyaç duyarsın
  • Herhangi bir dili bu kadar uzun uzadıya yerden yere vurmaya iten motivasyonun ne olduğunu merak ediyorum. Yazıdaki bazı geçerli noktalar bile yapıcı bir üslupla yazılmadığı için buna suçlama diyeceğim
    Eleştirilemeyecek dil mi var?
    O projede yaşanan başarısızlığı dile yükleyip kendini daha iyi hissetmek için yazılmış bir yazı mı? Yoksa herkesin aynı şekilde düşünüp çalışmadığını, birine dayanılmaz derecede batan bir şeyin başkasının neredeyse hiç gözüne çarpmayabileceğini anlayamamak mı?
    Gerçek ihtiyaçları karşılamayan diller genellikle kendiliğinden kaybolur; bunun için pek yardıma ihtiyaç duymazlar
    Go, “daha rafine” dillerden farklı yanları olsa da benim karşılaştığım projelerde harika çalıştı. Umarım yazar Go ile çalışmaya zorlanmıyordur. Topluluğun geri kalanı hizmetler geliştirmeye, Go ekibine geri bildirim vermeye ve dili prodüksiyonu bozmadan yavaş yavaş evrilirken izlemeye devam edecek

    • “Birini bu kadar uzun uzadıya suçlamaya iten şey nedir” sorusunun cevabı yazının içinde
      Özsel karmaşıklık gözlerini kapatınca ortadan kaybolmaz
      Karmaşıklığı umursamamayı seçersen, o karmaşıklığı sadece organizasyondaki başka geliştiricilere, operasyon ekibine, müşterilere, birilerine itmiş olursun. Artık her şeyin sorunsuz işlemesi için senin varsayımlarının etrafından dolaşmak zorunda olanlar onlar
      Son zamanlarda o “birileri” çoğu kez ben oluyorum ve artık yoruldum
      Go’nun karşılaştığın projelerde harika çalışmış olması doğal. C, C++, PHP, JavaScript de çalışıyor. Dünyamızda pek çok şey “çalışıyor”. Bir şerit daha eklemek de çalışıyor, polis devleti de çalışıyor
      Ama başka bir şey çok daha iyi çalışıyor olamaz mı?
    • Bu sadece birinin blogu ve içini dökmüş. Sorun değil; o kadar derin okumaya gerek yok
      Neden yazdığına gelince, muhtemelen asıl yazar kendi görüşünün “dünyada” yeterince temsil edilmediğini hissettiği içindir. Ben de Go hayranı değilim; 2022’de Go’nun popülerliği bana kafa karıştırıcı geliyordu. Çünkü epey belirgin bazı eksileri yok sayılıyor gibi görünüyordu
      PHP’nin kötü bir dil olduğuna dair uzun blog yazılarını artık pek kimse yazmıyor; çünkü bu konu zaten fazlasıyla işlendi
    • Herkes sadece sıkıcı ve klinik incelemeleri sevmez; biraz tutku ve mizah içeren yazıları sevenler de var
      Bu blog yazısının senin hoşuna gidecek şekilde yazılmamış olması, başkaları için değer taşımadığı anlamına gelmez
    • Go’dan neredeyse nefret etmeme yol açan çok öznel ve irrasyonel etkenlerden biri, yıllar boyunca Go fanatiklerinin Go’nun her parçası hakkında herkesi gaslight etmesiydi
      Go’nun yaptığı her şey, ister en temel uygulama olsun ister başka dillerin zaten daha iyi yaptığı bir şey olsun, vazgeçilmez, en iyi ve o sorunu çözmenin tek yolu gibi sunuldu
      Go’nun yapmadığı her şey ise gereksiz ve biz aydınlanmamış Go dışı kullanıcıları sözdizimsel şekere bağımlı kılmaya çalışan Big Complexity’nin komplosu gibi muamele gördü. Düzgün null işlemesi, hata işleme, daha az boilerplate, generics ya da her şey için özel durum üretmeden tutarlı çözümler oluşturmak gibi özellikler buna dahildi
      Bu başlıkta bile saman adam dövmeye devam ediliyor. Hata işleme konusu açıldığında, Go’nun hata işlemesinin çok daha iyi olabileceği gibi bariz bir gerçeği kabul etmek yerine JavaScript gibi şeyler ortaya atılıyor. Sanki Go’yu eleştiren kişi JavaScript’i hata işlemenin zirvesi sanıyormuş gibi
    • Bjarne bunu en iyi şekilde söylemişti. İki tür dil vardır: insanların şikâyet ettiği diller ve kimsenin kullanmadığı diller
  • Başka dillerle çalıştığım her seferinde, Go mükemmel bir dil olmasa bile hep ona geri dönmek istiyorum
    Kelimenin tam anlamıyla öylece çalışıyor olmasını seviyorum. Go’yu kur, kodu indir, kodu yaz; hepsi bu
    Hangi sürümü, runtime’ı, ayarı, build aracını, paket yöneticisini kullanacağını çözmen gerekmiyor. Sadece kurup Go kullanıyorsun
    Aynı deneyimi sunan başka bir dil muhtemelen en fazla Rust’tır
    Kendimize söylediğimiz bir yalan olabilir ama Python, TypeScript, Java kullandığım her seferinde sadece kod yazmak isterken ayarları, paket yöneticilerini, build araçlarını ve sürümle ilgili sorunları debug etmek ya da anlamaya çalışmak yüzünden programlama gözümde korkutucu hale geliyor

    • Go’nun gücü entegre araç zinciri. Yazıda söylendiği gibi birlikte çalışabilirliği daha zorlaştırıyor ama kişisel ve sınırlı deneyimime göre bu sık kullandığım bir kullanım senaryosu değil
    • Go’nun en çok övülmesi gereken yönü bu; Rust da kanallarla birlikte bunu benimsedi
  • Go eleştirilerini her okuduğumda aynı şeyi düşünüyorum. Yine de Go kullanmaya devam edeceğim
    Teoride kolayca belgelenebilecek çok sorunu olduğunu ve insanların pratikte de bunlara sıkça takıldığını anlıyorum; ama yine de gerçek işlerde hâlâ daha iyi programlama dillerinden biri gibi geliyor
    Genelde dezavantaj diye listelenen bazı şeylere katılmıyorum; örneğin her yerde hataları açıkça ele alma biçimini seviyorum. Diğer konularda katılıyorum ama bunlar bana diğer programlama dillerinin kusurlarından çok daha fazla batmıyor
    Go’nun başarılı olamadığı alanlara özellikle hassas olan insanların ömür boyu bundan şikâyet edecek olması üzücü geliyor
    Ama bir projede hangi dili kullanacağıma karar verirken “en iyi dil hangisi” diye bir sürü rasyonel argüman sıralamıyorum. Bana uyan, iyi yazılımı istikrarlı biçimde yazabileceğimi hissettiren ve çalışması keyifli olan dili seçiyorum
    Doğruluğa önem veren biri olarak o dilin Rust’a daha yakın olmasını isterdim ama şu anda öyle değil. Rust’tan nefret ettiğimden de değil; sadece acelem olduğunda elim onun üzerine gitmiyor
    Go’nun ne kadar berbat olduğuna dair artık yeterince çok yazı yazıldı. En azından birkaç yıl önce PHP hayranı olmanın nasıl bir his olduğunu artık biliyorum. Abartı, ama bence çok büyük bir abartı değil

    • “Go’nun başarılı olamadığı alanlara hassas insanlar ömür boyu şikâyet edecek” sözü, bu yazı için mükemmel bir onay gibi geliyor. Çünkü yazının özü kelimenin tam anlamıyla bu
      Go kullanacaksınız
      Ve pişman olacaksınız
      Ama o zaman artık çok geç olacak ve ona bağlanmış olacaksınız
      Yazar oldukça ikna edici bir argüman kuruyor ve buna karşı çıkmak da çok zor. Açıkça listelenen pek çok durumda ve teknik açıdan yetkin olmayan bir şirketin uygun olmayan bir teknolojiyi kullandığı birçok profesyonel senaryoda Go kötü bir seçimdir; bunu production’a koyduğunuza pişman olursunuz
      Şirketler sıkıcı araçlara bağlı kalmalı. Kişisel projeyse tabii ki istediğinizi yapabilirsiniz
    • Go’yu bir ölçüde seviyorum. Açık hata işleme bazen biraz can sıkıcı ama bu sadece işi bitirme biçimi
      Bunun dışında sadeliğini güçlü yön olarak görüyorum. Kullanımı güzel, öğrenmesi kolay ve genel olarak performansı da epey iyi. Her durum için seçmem ama iyi bir araç olduğu çok senaryo var
      Benzer şekilde Java ve Python’ı da bir ölçüde seviyorum; ikisinde de yeterince iyiyim. Bu diller, amaçladıkları şeyler için iyi araçlar
      İnsanların programlama dillerine neden bu kadar tutkuyla bağlandığını bilmiyorum. Diller araçtır. Bazı araçları daha çok sevebilirsiniz ama sevmediğiniz bir aracın geçersiz olduğu anlamına gelmez
    • “Bana uyan dili seçerim” herkes için en akıllıca seçimdir. Golang ancak yöneticiler zorla kullandırdığında sorun olur
    • Go’yu seviyorum ama çok fazla Go kodu yazıp okuduktan sonra if err != nil iblislerinin yüzüme vurduğu kâbuslar görüyorum
      Bu sorunu düzeltmek için çok sayıda iyi öneri vardı; ama aşırı muhafazakâr ve sesi çok çıkan topluluğun bir kısmı, hakarete yakın geri bildirimlerle tüm önerileri öldürdü
      Artık Go ekibi bu insanlardan psikolojik olarak çekindiği için hata işleme iyileştirmeleri savaşından vazgeçmiş durumda
      Her Go geliştirici anketinde topluluk ezici çoğunlukla hata işlemenin iyileştirilmesine oy veriyor; ama küçük bir aşırılık yanlısı azınlık tüm ilerlemeyi raydan çıkardı
    • Pek çok insanın Go’dan gerçekten nefret etmesinin nedeni, başka dil özelliklerini deneyimlemiş olmaları
      Go, hangi özelliklere ihtiyacın olacağına senin adına karar vereceği yönünde kibirli bir tavır takındı ve işte kullanabileceğin çok az şey sundu
  • O dönemki tartışmalar:
    (130 puan, 148 yorum) https://news.ycombinator.com/item?id=34188528
    (748 puan, 544 yorum) https://news.ycombinator.com/item?id=31205072

  • “Sözdiziminden çok anlambilime önem vermeye başladığım için Zig, Nim, Odin vb. dillere de bakmadım. Artık ‘daha iyi C’ ilgimi çekmiyor” diye bir bölüm var
    Yazının epey lafı uzattığını düşünüyorum. Go’nun “tesadüfi” olduğu kısmı saçmalık; çünkü Rust da kökeni ve tasarımı açısından en az onun kadar “tesadüfi”
    Gözüme çarpan bir şey, Nim’in kesinlikle “daha iyi C” olmadığı. Garbage collection var, reference counting de kullanabiliyor. İstersen daha iyi C gibi kullanabilirsin
    Nim’in tip sistemi, Go’nun sahip olduğu pek çok sorundan kaçınır; ama Rust kadar katı değildir
    Sonuçta Go ile çok fazla yazılım yazıldı ve dağıtıldı; hızlı çalışıyor, downtime’ı düşük, genel olarak etkili ve güvenlik sorunları da az görünüyor. Rust ile dağıtılmış yazılım projesinin çok daha az olduğunu düşünüyorum; Firefox da hâlâ %95’ten fazla C++

    • “Rust ile dağıtılmış yazılım projesi çok daha az ve Firefox da %95’ten fazla C++” sözü, bana 2022’deki şu tweet’i[0] hatırlattığı için ilginç
      Bu kavgada bir çıkarım yok; işte Python ve C++’ı memnuniyetle kullanıyorum. Rust ile yazılmış yazılım çok daha az olsa bile, yine de Rust ile çok fazla yazılım yazıldı ve dağıtıldı denebilir. Büyük şirketlerin yatırımları da göz ardı edilemez
      0: https://x.com/m_ou_se/status/1599173341117435905
  • Go’nun neden sürekli Rust ile karşılaştırıldığını anlamıyorum. En uygun karşılaştırma hedefi Java

    • Go’yu anlamanın doğru yolunun bu olduğunu düşünüyorum. Go, kodda güçlü tutarlılığın ve junior mühendislerin kısa uyum süresinin önemli olduğu ortamlarda sunucu geliştirmek için bir dil. Yani Java’nın kullanıldığı büyük şirket senaryolarına mükemmel uyuyor
      Go ile Rust karşılaştırmasının daha yaygın ama daha az faydalı olmasının nedeni muhtemelen ikisinin de yeni dil dalgasının parçası olması ve ikisinin de temelde statik linklenmiş binary’ler üretmesi
    • Go, Java’nın tekrarı değil, C’nin tekrarı
      Java’nın iyi bir seçim olduğu durumlarda Go gerçekten kötü bir seçim. Dilin kendisi sınırlı olmakla kalmıyor, ekosistemi de Java ile karşılaştırıldığında çok sınırlı
      Go, C# ve TypeScript’i ana dillerim olarak tutuyorum; bu kombinasyonun harika bir kapsama alanı sunduğunu düşünüyorum. Üretkenlik düşüşünü göze alabileceğim 6 ayım olursa ya da kalite gereksinimleri düşük bir proje çıkarsa Rust’ı ekleyeceğim
      Dili öğrenmek 1-2 hafta sürer, ama ekosistem içinde mühendislik yapmayı öğrenmek zaman alır
    • Go aslında C++ derlemesinin bitmesini beklerken yaratıldı. Amaç, ağ servisleri için C++’tan daha iyi bir şey yapmaktı ve bunda başarılı oldu. Sadece çıta epey düşüktü
      Performans kaygısının büyük olmadığı çoğu şirket ağ servisleri için C++ kullanmaz. Rust o zamanlar zaten olgun olsaydı iyi bir seçim olurdu; ama baştaki temel sorunlardan biri olan derleme süresi, Rust kod tabanlarında daha da kötü olabilir
      Gerçekte de Rust yerine Go kullanılan örnekler gördüm; en büyük neden Go’nun çok daha hızlı derlenmesiydi
    • Yeni yapılacak bir şeyi hangi dille yazacağına karar veren birinin Go ile Rust’ı birlikte değerlendirme olasılığı yüksek. Java’yı değerlendirme olasılığı ise çok düşük
      Rust ve Go yeterince farklı olduğu için her biri farklı durumlarda mı seçilmeli diye sorarsanız, evet. Zaten bu yüzden ikisi birlikte değerlendirilip biri seçiliyor
  • Bir zamanlar “daha iyi” bir Python arıyordum. C/C++’tan daha basit ve güvenli ama Python’dan daha hızlı olan, en önemlisi de tek bir binary üretebilen bir dil istiyordum
    Bu yüzden Rust’tan Hare gibi daha az bilinen dillere kadar hepsine baktım
    Go bariz seçim olmalıydı ama nedenini açıklayamadığım şekilde sözdiziminden hoşlanmadım. Rust’ı anlıyorum. Hatırlaması ve QWERTY olmayan klavyelerde yazması zor çok sayıda özel karakter kullanıyor, başka acı noktaları da var. Çeşitli Lisp’lerde sorun parantezler ve ters Lehçe gösterimdi. Ama Go’dan neden hoşlanmadığımı rasyonelleştiremiyorum
    Sonunda Python kodunu Nuitka ile derlemeye karar verdim. Hız artışı var mı bilmiyorum ama artık binary sunabiliyorum
    C#’a da giderek daha fazla bakıyorum, çünkü AOT derleme gelişiyor. Yine de varsayılan moddaki laf kalabalığını ve Windows’a fazla bağlı olmasını sevmiyorum
    Nim ve Crystal’ı çok beğendim ama küçük toplulukları bir engeldi. Yine de Nim’in bu kadar küçük bir toplulukla başardıklarından gerçekten etkilendim ve onun harika bir dil olduğunu düşünmeye başladım
    Bahsettiğim dillerden birini öğrenmek için kendimi motive etmeyi deneyeceğim

    • .NET Core, WPF gibi belirli framework’ler ve kimlik bilgisi depoları dışında Windows’a bağlı değil. WPF için de her yerde çalışan alternatifler var
      Bugünlerde kullanması gerçekten oldukça iyi
    • Nuitka’nın uyumluluğu iyi ama Python C-API’nin dezavantajlarını aynen taşıyor
      C-API’den vazgeçip Go veya Rust gibi dillere köprü kuran başka bir yaklaşım da var
      Ben birkaç yıl py2many üzerinde çalıştım. Bu yaklaşımla ilgili geri bildirim almak isterim