10 puan yazan GN⁺ 2024-12-16 | 5 yorum | WhatsApp'ta paylaş
  • Yazarın, Go dilini yıllarca kullandıktan sonra Java'ya geçerken hissettiği Go dilinin sınırlamalarını ve sorunlarını anlatan bir yazı
  • Go'nun basit ve sıkıcı (boring) bir dil olma özelliğinin bir avantaj değil, dezavantaj olabileceği görüşünü ortaya koyuyor
  • Go'nun felsefesi: Google'daki Go tasarım ekibi basitlik ve kısıtlılığı vurguladı, ancak bu yaklaşım kullanıcıların tekrarlayan işleri kendilerinin çözmesine yol açıyor

1. Go'nun "eğlenceli olmaması" bir dezavantaj olabilir

  • Russ Cox'un görüşü:
    • Go'nun "sıkıcı (boring)" olmasının bir avantaj olduğu vurgulanıyor
    • Döngü için yalnızca for var; filter, map, reduce gibi özellikler yerleşik gelmiyor
    • Diğer birçok dilde bulunan çeşitli gelişmiş özelliklerin olmaması, sadeliğin bir parçası sayılıyor
  • Reddit kullanıcı görüşü:
    • "Sıkıcı" ile "güçlü" arasındaki sınırın belirsiz olduğu söyleniyor
    • Go'nun eksik temel özelliklerinin bir gün dile eklenmesinin muhtemel olduğu savunuluyor
  • Üçüncü taraf paket bağımlılığı:
    • Eksik özellikleri tamamlamak için sık kullanılan samber/lo paketi:
      • filter, map, arama gibi temel işlevleri içeriyor
      • GitHub'da 18.1k yıldız almış ve 12.6k'dan fazla projede kullanılıyor
    • Bazı işlevler slices paketiyle eklenmiş olsa da hâlâ işlevsel olarak yetersiz bulunuyor
  • Yazarın şikayetleri:
    • Tekrarlayan döngülerin sürekli elle yazdırılması
    • filter ve map gibi işlemleri kısa ve temiz biçimde yapmanın zor olması
    • Ayrı receiver metodlarına çıkarmak mümkün olsa da bunun kodun sadeliğini bozması
  • Go'nun sadeliği birçok durumda avantaj olsa da, temel kullanım kolaylığı özelliklerinin eksikliği üretkenliği ve kod okunabilirliğini düşüren bir dezavantaja dönüşebiliyor

2. Clean Code ilkelerini zorlaştırıyor

  • Hata yönetimi sorunu:
    • Fonksiyonların çoğunda dönüş değerleri arasında error bulunuyor:
      • if err != nil kalıbı tekrar tekrar yazılmak zorunda kalıyor
      • Kodu düzenlemeye çalışırken bunun tersine daha karmaşık bir yapı oluşuyor
    • HTTP handler kodu, basit projelerde bile 20 satırın üstüne çıkabiliyor
      • Asıl hedefin yaklaşık 4 satırda kalmak olduğu belirtiliyor
    • Yazar, panic() ve recovery middleware kullanmayı düşünecek kadar bu hata işleme tarzından bıkmış durumda
  • Kısa isim teşviki:
    • Değişken, metod ve fonksiyon isimlerinde kısa adların teşvik edilmesi:
      • c, a gibi isimlerin ne anlama geldiği belirsiz kalıyor
      • Örneğin c, Command, Controller, Argument veya Amendment olabilir
      • Daha uzun isimler daha açık olabilirken Go felsefesi kısa isimleri tercih ediyor
    • Bunun ekip içi code review süreçlerinde, özellikle test metod isimleri gibi konularda bitmeyen tartışmalar doğurduğu söyleniyor
  • Go'nun felsefesi kodun kısa ve basit olmasını öne çıkarsa da, sonuçta Clean Code ilkelerine ters düşen karmaşıklık ve verimsizlik üretebiliyor

3. Bilerek küçük tutulan dil felsefesi ve DIY kültürü

  • Yerleşik özellik eksikliği:
    • Basit bir HTTP handler yazmak kolay, ancak temel middleware'lere ihtiyaç duyulduğunda (ör. exponential backoff, cross-site ayarları vb.) birçok paket aramak gerekiyor
    • Bu paketlerin (1) hâlâ bakım alıp almadığını ve (2) beklendiği gibi çalışıp çalışmadığını anlamak zor
  • Tekrarlayan işlerin artması:
    • Go'nun sadeliği korumaya yönelik tasarım felsefesi, geliştiriciyi sık sık "tekerleği yeniden icat etmeye" zorluyor
    • Örneğin basit bir filter işlevi bile elde yazılmak zorunda kalabiliyor
  • Olgunlaşmamış paket ekosistemi:
    • Birçok GitHub projesi terk edilmiş durumda ya da yalnızca birkaç sürüm yayımlamış
    • Nispeten genç bir dil olduğu için .NET/Java ile kıyaslamak adil olmayabilir, ancak pratikte Go'nun paket kararlılığı ve olgunluğu yetersiz görülüyor
  • ORM sınırlamaları:
    • Go'nun başlıca ORM paketi olan Gorm, Hibernate veya Entity Framework'e kıyasla işlev bakımından geride kalıyor
    • Tuhaf davranışlar ve yetersiz dokümantasyon sorunları var
    • Go topluluğunun tepkisi ise şöyle özetleniyor: "Go'da ORM'ye gerek yok, kendin yap!"
  • Go'nun sadeliği proje ve ekibe göre avantaj olabilir; ancak yerleşik gelmeyen özelliklerin eksikliği üretkenliği ve geliştirici deneyimini olumsuz etkileyebiliyor

4. Go'da tek bir yol diye bir şey yok

  • Tutarlılık ve birlik yanılsaması:
    • Table test yaklaşımı
      • stretchr/testify gibi test suite'leri kullanılıyor (557k projede kullanılıyor)
      • Table test içinde özel subtest'ler yazılıyor
    • Bu da Go'nun "tek ve birleşik yol" felsefesiyle pratik arasındaki farkı gösteriyor
  • Ekip içinde çatışma üretmesi:
    • Ekipler arasında test stili ve uygulama biçimlerine dair tartışmaların azalmadığı, aksine arttığı söyleniyor
    • Go'nun felsefesi ve tasarım ekibinin kendisinin de tutarlı olmadığı belirtiliyor:
      • Örneğin getter metod adlandırmasında bile uyumsuzluk var
  • Özellik reddi ve paket bağımlılığı:
    • Go ekibinin assertion özelliği eklemeyi reddetmesi ve bunun yerine sorunu programcının eksikliği gibi görmesi eleştiriliyor
    • Sonuç olarak gerekli işlevleri kullanmak için yine başka bir paket kurmak gerekiyor (go get)
  • Go sadelik ve birlik hedeflese de, gerçekte çok farklı uygulama biçimleri ve bunlardan doğan tartışmalar bulunuyor; dil tasarım felsefesindeki belirsizlik de bunu daha kötü hale getiriyor

5. Go'da debug yapmak eğlenceli değil

  • Debug sırasında ifade değerlendirme yok:
    • Debug oturumunda ifadeleri değerlendirmek veya nesnelerin özelleştirilmiş string gösterimlerini görmek mümkün değil
    • Bu da çalışma zamanında nesne durumunu net anlamayı zorlaştırıyor
  • Stack trace ve log'ların sezgisel olmaması:
    • Büyük testlerde (ör. CI içinde binlerce test çalışırken) hata olduğunda kafa karıştırıcı stack trace ve log'lar veriliyor
    • Sonuç olarak debug zorlaşıyor ve üretkenlik düşüyor
  • C tarzı debug deneyimi:
    • Go'nun debug araç zinciri C tabanlı çalışıyor:
      • C'ye benzer ilkel bir debug deneyimi sunuyor
      • Geliştirici dostu bulunmuyor
  • Rust ile karşılaştırma:
    • Rust'ın Go'nun bazı sınırlamalarını iyileştirdiği söyleniyor:
      • Açık ve yararlı hata bilgileri sunuyor
      • Hata mesajlarında doğrudan düzeltme önerileri veriyor
  • Go'nun debug deneyimi, optimize edilmiş binary üretimine öncelik veren tasarım anlayışına dayanıyor; ancak bunun bedeli geliştirici deneyiminin zayıflaması oluyor. Debug verimliliğinin önemli olduğu ortamlarda alternatif diller değerlendirmeye daha uygun olabilir

Özet: Go'nun uygunluğu ve sınırları

  • Go'nun yerleşik araçlarının avantajları:
    • Paket yönetimi, test ve performans izleme için temel araç zinciri sunuyor
    • Ek yapılandırma gerektirmeden kullanılabildiği için ilk geliştirme ortamı kurulumunu sadeleştiriyor
  • Sınırlar:
    • "Sıkıcı kod" ve tekrarlayan işler:
      • Go'nun araç zinciri işlevsel olsa da, kod yazarken tekrarlayan işleri (plumbing code) dayatıyor
      • Örneğin tekdüze sözdizimi ve sınırlı özellikler işi daha az ilgi çekici hale getiriyor
    • import cycle not allowed:
      • Testlerde döngüsel bağımlılığa (import cycle) izin verilmiyor
      • Domain-Driven Design (DDD) yaklaşımıyla çalışırken yapısal kısıtlar nedeniyle karmaşıklık artabiliyor
    • struct embedding tekniğine bağımlılık:
      • Garip ve kısıtlı struct embedding mekanizması kullanımda zorluk yaratıyor
  • Uygun kullanım alanları:
    • Altyapı geliştirme için uygun:
      • Docker, Drone, Hugo gibi sistem seviyesi araçlar Go ile yazılmış durumda
    • Hafif sunucular ve CLI uygulamaları geliştirmede kullanışlı
  • Uygun olmayan kullanım alanları:
    • Karmaşık kurumsal uygulamalar (ör. ERP sistemleri) geliştirmek:
      • Sınırlı dil felsefesi ve araçlar nedeniyle büyük iş mantığını yönetmek verimsiz hale gelebiliyor
  • Go, özellikle altyapı tarafındaki belirli işlerde çok verimli olabilir; ancak karmaşık iş alanı uygulamaları için uygun bir araç değildir. CTO, Google teknoloji yığınına eğilimli olsa bile teknoloji seçiminde dikkatli olunması gerektiği vurgulanıyor

5 yorum

 
secret3056 2024-12-17

Keşke Rust’taki ? olsaydı; şu ankinden çok daha iyi olmaz mıydı...

 
bbulbum 2024-12-17

Go kullanırken fark ettiğim şey, bunca zamandır ne kadar örtük hata işleme yaptığımı düşünmem oldu.
Elbette hata işlemeyi tek bir noktada ele almak yapısal olarak daha temiz görünebilir, ancak bir işlemin açıkça hata döndürebildiğini ortaya koyarken kodu daha güvenli bir şekilde yazmayı sağladığını düşünüyorum.

 
tsboard 2024-12-16

if err != nil {} bunun dürüst olmak gerekirse biraz can sıkıcı olduğu doğru. Dile getirilen eleştirilere de katılıyorum. Yine de bu dilin neyi amaçladığını net biçimde anlayıp hangi yönlerini daha fazla kullanabileceğimizi düşünürsek, işaret edilen eksilerine rağmen onu daha iyi değerlendirebileceğimizi sanıyorum. C'ye benziyor ama GC var, sınırlı da olsa generics desteği var, üstüne bir de cross-compilation yapılabiliyor! Böyle bakınca yine de oldukça cömert bir dil sayılmaz mı?

 
riki3 2024-12-16

Java'dan Go'ya geçerken ben de ilk başta benzer bir his yaşamıştım.
Şimdi ise Java'ya harcadığım zamana acıyacak kadar Go'dan keyif alıyorum. Karmaşık iş uygulamalarına uygun olmadığının söylenmesi, bana o uygulamanın sistemi basitleştirmek için yeterince kafa yorulmadığını düşündürüyor.

 
GN⁺ 2024-12-16
Hacker News görüşü
  • Java geliştiricileri Go'ya Java tarzını dayatınca sorunlar ortaya çıkıyor

    • Go felsefesi kısa vadede daha az kullanışlı görünse de uzun vadede büyük fark yaratıyor
    • JVM ekosistemine derinden gömülü kişiler Go'dan keyif almakta zorlanıyor
  • Birçok geliştirici fazla erken soyutlamaya gitmeye çalışıyor

    • Basit bir döngü yeterliyken gereksiz soyutlamalar oluşturuluyor
  • Go'nun standart kütüphanesi büyük, ancak her şeyi yapabilecek kadar büyük değil

    • Her projede tekerleği yeniden icat etme eğilimi var
    • Go, sunucu/CLI uygulamaları için ideal
  • Programlama dili seçiminden daha büyük zorluklar var

    • Go'nun mekanizmalarına ve felsefesine uyum sağlamak önemli
  • İnsanların Go'yu neden sevdiğini anlamak zor

    • Dilin kendisinden çok toolchain'i ve dağıtım kolaylığını tercih ediyorum
  • Go'nun çekirdek ekibinin yanlış kararları geri alması hayal kırıklığı yaratıyor

    • İyi bir paket sistemi ve araçlar mevcut
    • Karmaşık ERP sistemleri için Java daha iyi bir seçim olabilir
  • Go, UNIX benzeri sorunlara sahip

    • Karmaşıklığı kullanıcıya yükleme eğilimi var
    • Java'nın runtime'ı Go'ya kıyasla daha hızlı gelişiyor