3 puan yazan GN⁺ 2024-01-05 | 1 yorum | WhatsApp'ta paylaş
  • Go, 10 Kasım 2009’da açık kaynak olarak yayımlandıktan sonraki 14 yıl boyunca, yeni bir dil olmanın ötesinde üretim yazılımı geliştirmeyi kolaylaştırma biçimini hedefleyerek evrildi
  • Biçimsel şartname, birden çok derleyici uygulaması, kolay cross compilation, Go 1.0 sonrasında uyumluluk garantisi, standart kütüphane ve gofmt benimsenmeyi destekledi
  • Sunucu yazılımını yapılandırmaya yönelik eşzamanlılık güçlü bir yöndü; ancak başlangıçta paralellikle farkı ve uygun kullanım alanları yeterince açıklanmadığı için kafa karışıklığı yarattı
  • Arayüzler kütüphanelerin, testlerin, bağımlılık yönetiminin ve bileşim odaklı tasarımın temeli oldu; generics eksikliği ise sonraki 10 yılı aşkın süre boyunca polimorfik tasarımı zorlaştırdı
  • Paket yönetimi, dokümantasyon ve topluluk iş birliğinde çok sayıda deneme yanılma yaşandı; ancak Go, yazarı ve zamanı farklı olsa da benzer görünen ve derlenmeye devam eden bir ortamı hedefler

Go’nun hedefi: Dilden çok yazılım geliştirme biçimi

  • 10 Kasım 2023, Go’nun açık kaynak proje olarak yayımlanmasının 14. yıl dönümüydü
  • 2009’daki duyuru sırasında Ken Thompson, Robert Griesemer, Russ Cox, Ian Taylor, Adam Langley, Jini Kim ve diğerleri projenin kamuya açılışına tanıklık etti
  • Go’nun asıl hedefi yeni bir programlama dilinin kendisi değil, daha iyi bir yolla yüksek kaliteli yazılım yazmaktı
  • O dönemdeki darboğaz, dil özelliklerinden çok Google’da modern sunucu yazılımı üretme sürecinin karmaşıklığındaydı
    • Bağımlılık denetimi
    • Büyük ekipler ve değişen insan kaynağı yapısı
    • Bakım kolaylığı
    • Verimli test
    • Çok çekirdekli CPU ve ağ kullanımından yararlanma
  • Go bugün de üretim yazılımı oluşturmayı daha kolay ve üretken kılan bir proje olarak tanımlanır

Gopher maskotunun oluşturduğu topluluk kimliği

  • Go gopher, Go’nun başarısındaki erken etkenlerden biriydi
  • Renee French’in yaptığı gopher, Go programcılarının paylaştığı bir sembol ve topluluğun bayrağı rolünü üstlendi
  • GopherCon adlı konferansta olduğu gibi gopher, teknik mükemmeliyet ile eğlencenin bir arada bulunduğu bir proje atmosferi yarattı
  • Creative Commons Attribution lisansıyla yayımlama tercihinin artıları ve eksileri vardı
    • Remiksleri ve varyasyonları teşvik ederek topluluk ruhunu büyüttü
    • Attribution koşulu nedeniyle tartışmalar çıkması veya Renee French’in yapmadığı çalışmalara yanlış kredi verilmesi gibi sorunlar da yaşandı
  • Maskotun özgün ruhunu koruyacak şekilde yönetilmesi hâlâ zorlu bir görev olarak duruyor

Go’nun doğru yaptığı teknik seçimler

  • Önce biçimsel şartname yazılarak derleyici uygulamalarının davranışı sabitlendi ve birden fazla uygulamanın aynı davranış üzerinde uzlaşması sağlandı
    • Tek bir derleyicinin tek başına şartname olamayacağı değerlendirmesi yapıldı
    • İlk şartname taslağı, Sydney Darling Harbour’daki bir binanın 18. katında yazıldı
  • Birden çok derleyici uygulaması, dili ve şartnameyi rafine etmeye yardımcı oldu
    • Ian Taylor, 7 Haziran 2008’de Go taslak şartnamesini okuyup bir gcc front-end’i yazdığını e-postayla bildirdi
    • Sonrasında da çeşitli uyumlu uygulamalar ortaya çıktı
  • Cross compilation’ın kolaylaştırılması sayesinde geliştiriciler istedikleri platformda çalışıp gereken platforma dağıtım yapabildi
  • Go 1.0’da dili toparladıktan sonra uyumluluk garantisi getirme kararı, Go’nun benimsenmesinde büyük etki yarattı
    • Güçlü uyumluluğu korumanın maliyeti olsa da yeni Go sürümlerinin projeleri bozacağı endişesini azalttı
  • Standart kütüphane, 21. yüzyıl sunucu kodu yazmak için gereken işlevlerin çoğunu sundu ve topluluğun aynı araç kutusu üzerinde çalışmasını sağladı
    • Başlangıçta Go kodu kurmak için başka bir yer bulunmadığından kütüphanenin büyüdüğü yönler de vardı
    • Varyant kütüphanelerin çoğalmasını azaltmaya ve topluluğu birleştirmeye yardımcı oldu

Araçlar ve gofmt’nin yarattığı geliştirme deneyimi

  • Go, ayrıştırması kolay bir dil olarak tasarlandığı için araç geliştirmeyi kolaylaştırdı
  • Başlangıçta IDE gerektiği düşünülüyordu; ancak araçlaştırma kolaylaştıkça zaman içinde IDE’ler Go desteği verdi ve gopls de ortaya çıktı
  • Derleyiciyle birlikte otomatik test, coverage ve kod vetting gibi yardımcı araçlar sağlandı
  • go komutu tüm build sürecini birleştirdi; birçok proje Go kodunu derlemek ve bakımını yapmak için gerekenlerin çoğunu bu komutla çözebildi
  • gofmt, yalnızca Go’yu değil tüm programlama topluluğunu etkileyen bir araç hâline geldi
    • Robert Griesemer, en baştan gofmt yapılması gerektiğini savundu
    • gofmt öncesinde otomatik formatter’ların kalitesi yüksek olmadığı için neredeyse hiç kullanılmıyordu
    • Boşluk ve satır sonları tartışmalarına harcanan zaman azaldı
    • gofmt’nin içi bir kütüphaneye dönüşünce AST ayrıştırılabilir, değiştirilebilir ve insan tarafından okunabilir çıktıya yeniden dönüştürülebilir hâle geldi
    • simplifier, analyzer ve kod coverage araçları gibi başka araçlar da mümkün oldu

Eşzamanlılık: Güçlüydü ama açıklaması geç kalan özellik

  • 2002’de Google yazılımı thread’lerden büyük ölçüde kaçınıyor, John Ousterhout’un “threads were bad” görüşünü alıntılayarak kullanımı engelleyen bir atmosfer oluşuyordu
  • Go, eşzamanlılığın pthread gibi düşük seviyeli paketlerden daha iyi bir yöntemle kullanılabileceği deneyiminden yola çıktı
  • Go, programlama dünyasının eşzamanlılığı güçlü bir araç olarak benimsemesinde önemli rol oynadı
    • Özellikle çok çekirdekli ve ağ ortamlarında etkisi büyüktü
    • Günümüzde ana akım dillerin çoğunda eşzamanlılık desteği var
  • Go, coroutine, task, thread gibi adlar kullanmak yerine goroutine adlı yeni bir terim oluşturdu
  • async/await pthread’e göre büyük bir iyileştirme olsa da goroutine, channel ve select ile karşılaştırıldığında uygulayıcılar için daha kolay ve küçük olsa bile karmaşıklığın bir kısmını programcıya geri yükleyebilir
    • Bob Nystrom’un “What Color is Your Function?” problemi örnek olarak kullanılır
    • Go’nun CSP modeli prosedürel dillere iyi uyar; ancak doğru uygulamak için runtime karmaşıklığı gerekir
    • Tek bir ortamda birden fazla eşzamanlılık uygulaması bulunması sorun yaratabileceğinden Go bunu kütüphaneye değil dile koydu

Eşzamanlılıkta yanlış yapılan iki şey

  • Go ekibi, eşzamanlılığın nerede kullanılması gerektiğine dair başlangıçta yeterince yönlendirme yapamadı
    • Ana kullanım alanı, net/http gibi çekirdek kütüphanelerde sunucu yazılımını daha basit hâle getirmekti
    • Her programın her yerinde kullanılması gereken bir özellik değildi
  • Paralellik ile eşzamanlılık arasındaki farkın geç açıklanması da bir sorundu
    • Birçok geliştirici kodunu goroutine’lerle paralelleştirip daha hızlı hâle getirmeye çalıştı; ancak yavaşladığını görünce şaşırdı
    • Eşzamanlı kod, yalnızca problemin kendisi paralel olduğunda, örneğin HTTP isteği işleme gibi durumlarda paralelleştirme ile hızlanabilir
  • Bunu telafi etmek için 2012’de Waza’da “Concurrency is not Parallelism” sunumu yapıldı
  • Bu açıklamanın daha erken yapılması gerekirdi
  • Buna rağmen Go, sunucu yazılımını yapılandırma biçimi olarak eşzamanlılığı popülerleştirmeye katkı sundu

Arayüzler ve bileşim odaklı tasarım

  • Arayüzler, eşzamanlılıkla birlikte Go’yu ayırt eden temel fikirlerden biridir
  • Go arayüzleri, özgün davranış odaklı nesne yönelimli tasarıma Go’nun cevabına yakındır
  • Bir tipin hangi arayüzü uyguladığını önceden bildirme gerektirmeyen dinamik yaklaşım başlangıçta eleştirildi, ancak Go tarzı programlama için önemliydi
  • Standart kütüphane, test ve bağımlılık yönetimi arayüzlerin açık yapısına büyük ölçüde dayanır
  • Go’nun sort’u, arayüz üzerinde çalışan fonksiyonlar olarak uygulanır
    • Birçok kişinin alışık olduğu nesne yönelimli stilden farklıdır, ama güçlü bir fikirdi
  • Reader, Writer, empty interface gibi küçük arayüzler Go kütüphanelerinin temeli oldu
    • Bu ünlü üç arayüzün ortalama olarak her biri 2/3 metoda sahiptir
    • Küçük metot kümeleri Go’ya özgü bir deyim hâline geldi

Generics etrafındaki uzun dolambaçlı yol

  • Go ekibi, generic programlamanın algoritmalardan önce tipleri düşünmeye yöneltme eğilimini görmüştü
    • Erken soyutlamadan çok organik tasarımı tercih etti
    • Container’lardan çok fonksiyonlara önem verdi
  • Go, map, slice, array, channel gibi generic container’ları dile dahil etti; ancak bu generic’liği kullanıcılara doğrudan sunmadı
  • Basit programlama işlerinin çoğu için bu tiplerin yeterli olduğu düşünüldü; ancak yeterli olmadığı durumlar da vardı ve bu sınır bazı kullanıcılar için rahatsızlık yarattı
  • Arayüzler Go programlamasının temeli olduğundan, yeni polimorfizm modelinin arayüzlerle mutlaka iyi uyum sağlaması gerekiyordu
    • Birçok deneme ve durdurulan uygulama oldu
    • Uzun tartışmaların ardından Phil Wadler’ın yönettiği tip teorisyenlerinden de yardım alındı
  • Sonunda Go, arayüzleri “metot kümesi”nden “tip kümesi”ne genelleştiren bir yaklaşımla generics’i tasarladı
  • “generics” terimi veri yapısı odaklı polimorfizmden gelen bir söz olduğu için Go’nun sunduğu parametric polymorphism’i tam olarak ifade etmez; ancak pratikte generics sözü kullanılmaya başlandı

Derleyici: Başta C, sonra Go

  • İlk Go derleyicisinin C ile yazılmış olması dil topluluğunun bir kısmını rahatsız etti
    • LLVM gibi toolkit’lerin kullanılması veya Go’nun kendi kendini barındıracak şekilde self-hosting yapması gerektiği görüşü vardı
  • İlk derleyicinin C ile yazılmasının nedeni pratikti
    • Yeni bir dili bootstrap etmek için mevcut bir dile ihtiyaç vardı
    • Ken Thompson zaten bir C derleyicisi yazmıştı ve onun iç yapısı Go derleyicisinin temeli olabilirdi
    • Dili tasarlarken aynı zamanda o dille derleyici yazmak, tasarımı derleyici yazmaya uygun bir dile doğru eğebilirdi
  • İlk derleyicinin ürettiği kod sıradandı ve iç yapısı da temiz değildi; ancak küçük, tanıdık ve hızlıca değiştirilmesi kolaydı
  • Otomatik büyüyen segmented stack eklenmesi bu seçimin avantajlarını gösterdi
    • LLVM gibi toolkit’ler kullanılsaydı ABI ve garbage collector desteği değişikliklerini de kapsaması gerekeceğinden entegrasyon zor olurdu
  • Aslen Plan 9 derleyici ailesi yaklaşımından gelen yapı, cross compilation’a da iyi uydu
  • Go 1.5’te Russ Cox, derleyiciyi C’den Go’ya yarı otomatik çeviren bir araç yazdı
    • Bu noktada dil tamamlanmış olduğundan, derleyici odaklı dil tasarımı kaygısı ortadan kalktı
    • Go’ya taşındıktan sonra test, araçlar, otomatik yeniden yazım ve performans analizi gibi Go’nun avantajları derleyici geliştirmeye de uygulanabilir hâle geldi
  • Bugün LLVM tabanlı Go derleyicisi ve başka birçok derleyici de mevcut

Açık kaynak proje yönetimi ve topluluk

  • Go, başarılı olmak için en başından açık kaynak proje olması gerektiğini değerlendirdi
  • Ancak temel fikirler ve davranış uygulaması toparlanana kadar kapalı geliştirme yapmanın daha üretken olacağı düşünüldü
    • Açılıştan önceki ilk 2 yıl, hedefleri netleştirmede önemliydi
  • Açık kaynağa geçtikten sonra topluluk girdisi ezici düzeydeydi; özellikle Ian Taylor soruları yanıtlamaya çok zaman ayırdı
  • Windows port’u, Alex Brainman’ın rehberliğinde tamamen topluluk tarafından gerçekleştirildi
  • Go ekibinin toplulukla iş birliği yapmanın en iyi yolunu anlaması uzun zaman aldı
    • İyi iletişim kurduklarını düşünüyorlardı; ancak yanlış anlamalar ve beklenti uyuşmazlıkları yüzünden zaman kaybedildi
  • Go projesi, kodu hızla kabul edip sonra temizlemek yerine, merge öncesinde yüksek kod kalitesi sağlamayı seçti
    • Zorunlu kod incelemesi
    • Ayrıntılara titiz dikkat
  • Bu yöntem topluluğa daha fazla yük bindirdiğinden, katılımcılar değerini anlamazsa hoş karşılanmadıklarını hissedebilir
  • Go projesinin depo geçmişi SVN, Perforce, Mercurial ve Git’ten geçti; ancak Russ Cox geçmişi koruduğu için bugünkü Git deposunda da erken SVN değişiklik kayıtları yer alıyor
  • Google, Go’yu destekler; ancak Go ekibinin gündemini belirlemez
    • Google içindeki büyük Go codebase’i sürümleri test etmek ve doğrulamak için kullanılır
    • Akış, açık depodan Google’a içeri alma şeklindedir; tersi değildir
    • Çekirdek Go ekibine Google maaş öder, ancak ekip bağımsız hareket eder

Paket yönetimindeki deneme yanılmalar

  • Go dilinin package tasarımının kendisi mükemmeldi; ancak paket yönetiminin geliştirme süreci iyi ilerlemedi
  • import ifadesinde yolu sıradan bir string olarak belirtmek önemli ve esnek bir seçimdi
  • Sorun, yalnızca standart kütüphanenin bulunduğu durumdan web’den kod getirme yöntemine geçişin zorlu olmasıydı
  • İlk Go ekibi Google’ın monorepo’suna ve head’den build etme yöntemine alışıktı
    • Birden fazla paket sürümü bulunan paket yöneticilerini kullanma deneyimi yeterli değildi
    • Bağımlılık grafiğini çözmenin teknik karmaşıklığını en baştan ele alamadılar
  • deps.dev çalışması bu soruna yönelik bir tür telafi gibi ele alındı
  • Toplulukla birlikte bağımlılık yönetimi sorununu çözme girişimi iyi niyetliydi; ancak nihai tasarım ortaya çıktığında birçok topluluk üyesi dışlanmış hissetti
  • Bu deneyim, topluluk katılımının gerçekte nasıl yürütülmesi gerektiğine dair bir ders oldu ve sonrasında çok iyileşti
  • Bugün tasarım kararlı, teknik olarak güçlü ve çoğu kullanıcı için iyi çalışıyor gibi görünüyor

Dokümantasyon ve çalıştırılabilir örnekler

  • Başlangıçta çok dokümantasyon yazıldı; ancak topluluğun istediği seviyeden farklıydı
  • En eksik kalan nokta, en basit fonksiyonlar için bile kullanım örnekleri gerektiğiydi
    • Ne yaptığını söylemektense nasıl kullanılacağını göstermek daha değerliydi
  • Günümüzde dokümantasyonda birçok örnek var ve çoğu açık kaynak katkıcıları tarafından sağlandı
  • Go, erken dönemde örneklerin web üzerinde çalıştırılabilir olmasını sağladı
    • 2012 Google I/O sunumunda eşzamanlılığı gösteren kod parçalarının tarayıcıda çalıştırılabilmesi sağlandı
    • Andrew Gerrand bunu mümkün kılan web teknolojisini yazdı
    • Sonrasında bloglara ve çevrimiçi paket dokümantasyonuna da dağıtıldı
  • The Go playground, insanların özgürce kod deneyip geliştirebileceği açık bir sandbox olarak sunulur

14 yıl sonra Go’nun ulaştığı nokta

  • Go, dil tasarımı ve geliştirme sürecinde alınan kararlar sayesinde basit bir programlama dilinin ötesine geçip yazılım yazma biçimi olarak yer edindi
  • Go’nun ulaştığı noktaya şu unsurlar katkı sağladı
    • Sunucu kodu için gereken temel işlevlerin çoğunu uygulayan güçlü standart kütüphane
    • Dilin birinci sınıf bileşeni olan eşzamanlılık
    • Kalıtımdan çok bileşime dayalı yaklaşım
    • Bağımlılık yönetimini netleştiren paketleme modeli
    • Entegre ve hızlı build ile test araçları
    • Katı ve tutarlı formatlama
    • Zekice numaralardan çok okunabilirliğe önem veren tutum
    • Uyumluluk garantisi
  • Go topluluğu çeşitli ve aktif Gopher’lardan oluşur ve projenin başarısında kilit rol oynar
  • Sonuç olarak Go kodu kim yazmış olursa olsun benzer görünür ve benzer çalışır; dilin farklı alt kümelerini kullanan hizipler görece azdır ve zaman geçse de derlenip çalışmaya devam etmesi garanti edilir
  • Bu özellikler, başlıca programlama dilleri arasında nadir görülen bir sonuç olarak değerlendirilebilir

1 yorum

 
GN⁺ 2024-01-05
Hacker News görüşleri
  • Kilit kişilerin zaman ayırıp geriye dönük değerlendirme yazmaları gerçekten takdire değer; şu anda gerçekten değişim yaratmak isteyenler için de çok yardımcı oluyor.
    Yine de Rob Pike'ın Go'nun neyi iyi yaptığını yeterince açık anlattığını sanmıyorum. Go yalnızca dilin kendisini değil, projeye etki eden güçleri de iyi yönetti: hedef kullanım alanını sistem programlamayla sınırladı, dili ve ilkeleri net biçimde tanımladı, yayımlamadan önce sorunları düzeltmeye öncelik veren kalite odaklı tutumu korudu; dil, sürüm ve ana mesajlar üzerinde sıkı kontrol sağlarken alt alanlarda topluluğun öncülük etmesine alan bıraktı.
    Daha az takdir edilen nokta, Google'ın kendisinin çok fazla müdahale etmemiş olması. Bunun nedeni Go'nun Google'ın hedeflerine gerçekten katkı sağlaması ve önemli olması olabilir. Bugün yeni projelerde bunun hâlâ mümkün olup olmayacağı ise soru işareti.
    Dart'ın Flutter dışında neredeyse hiç benimsenmemesi, uygulama kodunun sistem kodundan çok daha fazla olduğu gerçeğiyle karşılaştırıldığında ilginç. Go, sunucu tarafı yazılımları Java'nın hantal ortamından native container'lara taşıyan kilit teknolojiydi ve son 10 yıldaki web uygulaması altyapısının büyük bölümünün temelini oluşturdu. Bu büyüme sırasında bile ekip küçük kaldı ve kilit kişiler de ayrılmadı; bunun gelecekte de böyle olup olmayacağını bilmiyorum.

    • Go'da garbage collection var ve green thread'leri de içeren ağır runtime'ı nedeniyle C birlikte çalışabilirliği zahmetli ve yavaş hale geliyor.
      Bu yüzden tasarım gereği sistem programlama dili olmaya uygun değil. Başlarda kendini böyle adlandırdığı için tuhaf bir efsane uzun süre devam etti, ama o ifadenin birkaç yıl önce kaldırılmış olduğu anlaşılıyor.
      Go, C veya Rust'ın rakibinden çok Java ailesinin rakiplerine daha yakın; gerçek kullanım alanlarına bakınca bu görülüyor. Yine de sınırlı tip sistemi ve çok iyi concurrency desteği nedeniyle stack içinde sık sık biraz daha alt katmanlarda yer buluyor.
    • Topluluğun öncülük ettiği kısmına katılmak zor. Hâlâ Google karar veriyor hissi güçlü.
      Özellikle sürüm yönetimi böyleydi. Başta Go sorunun kendisini bile kabul etmedi; topluluk mutabakatı büyüyünce de önceki tartışmaları unutup artık modules ile ilerleyeceğiz diye karar verdi.
      Cloudflare yaz saati uygulaması kaynaklı kesinti yaşayana kadar monoton artan zamanı (monotonic time) public API yapmak istemediklerini de hatırlıyorum.
    • Java geliştiricisiydim ve şimdi Go'yu seviyorum, ama eski Java çalışma arkadaşlarımın Go'yu sevip sevmeyeceğinden emin değilim. Go, yeni bir dil olduğu dönemde bile biraz sıkıcı bir dildi.
      Java dünyasında harika streams gibi yeni özellikleri kullanıp kod tabanını refactor etmenin keyfi var. Go'da ise keyif, en basit ve en sıradan soyutlamayı bulmaktan geliyor.
    • Dart üzerinde çalışıyorum. Dart'ın Flutter dışında benimsenmemesi eleştirisinin o kadar yıkıcı olduğunu düşünmüyorum.
      Her dilin belirli alanlara uygun kütüphane ve frameworklere ihtiyacı var. Flutter, Dart ile istemci uygulamaları yazmaya yönelik bir framework; Flutter olmasaydı Dart dilini ne kadar sevseniz de Android ve iOS'te ekrana piksel çizmenin yolunu bulmak için muazzam zaman harcamanız gerekirdi.
      Uygulama yazan herkes bir kütüphane ve framework stack'i üzerine inşa eder. Go ile Flutter'a bağlı Dart arasındaki fark, sunucular için gereken networking, serialization ve cryptography gibi alan kütüphanelerinin Go'da standart kütüphaneye dahil olması ölçüsünde.
      Dart, collections ve async gibi temel öğeleri yerleşik kütüphaneler olarak içeriyor; ancak alan bazlı işlevler için Flutter gibi harici paketlere dayanıyor. Bunda Dart'ın çok erken dönemden itibaren sağlam bir paket yönetimi yaklaşımına sahip olması büyük rol oynuyor. Dart ekibinin yazıp bakımını yaptığı pek çok temel kütüphane de yerleşik olmak yerine paket yöneticisiyle dağıtılıyor; bu şekilde geliştirmek çok daha kolay.
      UI framework'lerinin ömrü dillerden daha kısa olma eğiliminde olduğu için Flutter'ın Dart standart kütüphanesine gömülü olmamasının daha iyi olduğunu düşünüyorum. Flutter harika, ama 20 yıl sonra daha iyi bir şeyin çıkmasına şaşırmam; o zaman Flutter yerleşik değilse Dart kullanıcıları daha kolay geçiş yapabilir.
    • İşten çıkarmalar sırasında temel FOSS ekiplerini kestiler; yönetim gerçek FOSS'tan hoşlanmıyor. Çünkü Ruth'un spreadsheet'inde iyi görünmüyor.
      Android gibi sahte FOSS stratejik olarak tolere ediliyor, ama onun dışında reklam tıklamalarına dönüşmüyorsa işe yaramaz gözüyle bakılan bir hava var.
  • 2012'de Python geliştiricisi olarak Modbus için bit manipülasyonu yapmam gerektiğinden Go'ya el attım. O kodu dağıtmadım, ama bit ve byte'larla uğraşmanın bu kadar kolayca çalışması beni şaşkına çevirmişti.
    10 yıl geçti ve neredeyse tam zamanlı sayılabilecek birkaç Go işi yaptıktan sonra bile, çoğu şeyin öylece çalışması hâlâ şaşırtıcı.
    Go dilini ve Go topluluğunu seviyorum. Rob, Ian, Russ ve Go'yu yapan diğer kişilerin çalışmalarına minnettarım; bu sunumun/yazının toplulukla yaşanan “çetin dönemleri” dürüstçe ele almasını da takdir ediyorum.
    Ancak o dönemi yaşamış biri olarak, özellikle paket yönetimi karmaşasında nasıl davrandıklarını tam olarak bilmediklerine inanmak çok zor. Yine de yazının, bugün iyi bir çözüme ulaşıldığı yönündeki değerlendirmesi de doğru.
    Önümüzdeki 10 yılda Go'nun ve Zig, Deno gibi ondan ilham alan benzer dillerin sağlıklı topluluklarla büyümeyi sürdürmesini umuyorum.

    • Go çekirdek ekibinde en sevdiğim şey, her türlü isteğe “hayır” diyebilmeleri ve generics için “doğru implementasyonu bekleyelim” diyebilmeleriydi.
      Programcıdan çok hesaplamalı biyolog olduğum için Go kullanımım düzensiz, ama Go'ya geri döndüğümde eski kodum derleniyor ve dil beklediğim gibi davranıyor.
      Aynı zamanda Rob Pike'ın parlak özelliklerin hepsini kabul etmemekle birlikte, topluluk katılımını öğrenme sürecindeki hataları kabul etmesini olumlu görüyorum.
    • Python'dan geçmiş biri olarak konuşuyorum. Son zamanlarda Bard, GPT-4 gibi yapay zeka araçlarıyla eski Python yardımcı araçlarını doğrudan Go'ya dönüştürüyorum.
      Bazıları hemen çalıştı; bazılarında yapay zeka modeli API bilgilerini biraz eski bildiği için ufak dokunuşlar gerekti.
      Yine de programı sunucuya scp ile kopyalayınca öylece çalışması, Python'da her seferinde “bu seferki moda venv sistemi neydi” dansını yapmaya kıyasla şaşırtıcı.
    • Zig ve Deno'nun Golang ile çok iyi karşılaştırma nesneleri olduğunu sanmıyorum. Daha ziyade Elixir ve ReasonML daha benzer; Google içinde bakarsak Dart da var.
  • Güzel bir yazı ama epey kendini tebrik eder gibi de görünüyor. Dilin daha derin sorunlarına dair bir kabul bekliyordum; ama galiba ana fikir, onlara göre dilin kusursuz, sorunun ise bende olması
    Bu yüzden Go’yu önermek zor. Tip sistemi, hata işleme, güvenli olmayan eşzamanlılık, aşırı basit sözdizimi, nil, varsayılan sıfır değerleri ve ihmal edilmiş çok sayıda ana akım paket gibi sorunları var
    Şu anda ana dil olarak Rust kullanıyorum. Ekosistemi canlı ve Go’nun olmadığı pek çok açıdan bir vizyonu var
    Daha sivri söylemek gerekirse, Go’nun PHP ile arka uç dili olarak rekabet ettiği dönemde kendi zamanı varmış gibi geliyor

    • Bunun tartışmaya pek katkı sunduğunu sanmıyorum. Somut noktalar olmadan Rust savunuculuğu gibi okunuyor
      İlk paragraf “sevmiyorum”, ikincisi alay, üçüncüsü de “sevmiyorum”, dördüncüsü “Rust daha iyi”, beşincisi yine alay gibi görünüyor
    • Plan 9 kökenli bilim insanları kendi markalarını fazla seviyor. 2012’de Go kullanmaya başladım ama deps.dev kaldırıldıktan sonra vazgeçtim
      Birkaç yıl sonra şirkette işleri bitirmek için ekibe Go’yu sokmaya çalıştım; başka bir mühendis zaman ayırıp dili inceledi ve neden pek iyi olmadığını madde madde sıraladı, haklıydı
      Esas nokta, basit olsa da hata işleme ve kullanılmayan import’lar gibi küçük şeylerin kullanımı acı verici hale getirmesiydi. Şahsen hata işlemeyi seviyordum ama tip sistemini sevmiyordum
    • Rust öğrenmeden önce Go kullandım ve ikisinin farkını görünce fikrim ciddi biçimde değişti
      Daha önce OCaml kullandığım için try/catch ya da nil yerine Option ve Result tiplerinin değerini biliyordum, ama kolay olduğu için Go kullanıyordum. Ne var ki bu kolaylığın uzun vadeli bakım maliyeti var. En baştan doğru yapmak ve sonradan zorluklarla karşılaşmamak daha iyi
      Hafife almak istemem ama Go için, son 50 yılın programlama dili ilerlemelerini alıp çöpe atan bir dil olduğu açıklamasını sıkça duydum
    • Programlama dillerine dair değerlendirmeye katılıyorum; ama Go’yu savunmak gerekirse Go, programlama dilinin kendisiyle ilgilenmeyen insanlar için, büyük ölçüde de böyle insanlar tarafından yapılmış bir dil
      Bunu kötü anlamda söylemiyorum. Rob Pike eşzamanlılığın güvenli olmamasını ya da nilin milyar dolarlık hata olmasını umursamıyor; Go kullanıcılarının çoğu da umursamıyor
      Bu Go’yu iyi bir dil yapar mı, hayır. Ama mesele bu değil. Go, kullanımı kolaylaştıran ikna edici araçlarla birleşmiş, pratik ve yeterince iyi bir dil. Programlama dilleri dünyasının Crocs’u gibi
    • Rust öğrendim ama Rust kullanıcı topluluğu yüzünden dili sevmek imkânsız. Yıllar geçmesine rağmen değişmedi; hatta daha kötüye gittiyse gitmiştir, iyileşmedi
      Yüksek bütünlük ve güvenlik gerekiyorsa Ada ya da biçimsel doğrulama eklenmiş Ada/SPARK kullanırım. Bunun dışında Go, Rust’tan çok daha yüksek üretkenlik sağlıyor
      Şahsen Rust’ı, C++ gibi aşırı mühendisliğin başlıca örneklerinden biri olarak görüyorum
  • Kulağa kırgın gelebilir ama 10 yıl önce go-nuts üzerinde alay edildim ve Rob Pike’tan da küçümseyici bir yanıt aldım. Çünkü go get ile ağ üzerinden modül import etme biçiminin çalıştığını, başlangıç dokümanlarının genelinde teşvik edildiğini ve tüm toplulukta bu şekilde kullanıldığını; bunun da nihayetinde zararlı ve dar görüşlü olduğunu söyleme cüretinde bulunmuştum

    • Go’nun paket sistemi, özellikle modules öncesindeki hali, Google monorepo içinde kullanılmak üzere tasarlanmış daha sınırlı bir sistemin üstüne dış dünya davranışını zorla ekleyen bir hack gibi hissettiriyordu
      Garip küresel ad alanı ağacı o ortamda mantıklı; check-in edilmiş kod üretim çıktılarına yapılan vurgu da Google’ın monorepo’ya derleme çıktıları bile koyduğu düşünülünce anlaşılır
    • Yine de Go’nun ortaya çıkardığı sonucun diğer dillerinkinden daha iyi olması ilginç
      Elbette v2 sorunu ya da bitmeyen v0 sorunu var. Yine de npm kullanmaktan ya da insanın istavroz çıkaracağı Python’dan bir şeyle uğraşmaktan daha iyi
    • Rob Pike’ın 2000’den sonra keşfedilen programlama dili teorisine ne kadar yabancı olduğunu dünyaya göstermiş oldu
  • Bu yazı ACM’de yayımlanmış yazının [1] daha kişisel bir sürümü gibi görünüyor. İki yazı da dil belirtimi açısından harika yeni bir programlama dili yapmak yerine, programlama dilinin çevresindeki şeyleri çok iyi kurduklarını ve bunun daha da önemli olabileceğini kabul ediyor
    Gönderilen yazıda interface kullanımı yaklaşımını ve eşzamanlılık yaklaşımını icat ettiklerini söylüyor. Ama goroutine, Haskell thread ile aynı; interface’ler de şu anki gibi generic argümanları desteklediğinde Haskell typeclass’larına çok benziyor. Haskell’in Go’dan önce geldiği düşünülürse, prosedürel programcıların fonksiyonel programlama fikirlerinin gücünü bağımsız biçimde keşfetmesini izlemek ilginç
    Go’nun bir dil yeniliği, interface implementasyonunun implement ettiği interface’i kendisinin bildirmek zorunda olmaması. Güvenlik açısından berbat, ama pratikte neredeyse hiç sorun çıkarmıyor ve Haskell ile Rust’ta yaşanan korkunç döngüsel bağımlılık sorunlarını ortadan kaldırıyor
    [1] https://cacm.acm.org/magazines/2022/5/260357-the-go-programm...

    • Interface’lerin yapısal tip olmasının, bu özelliğin dilin geneli, dahası deyimler ve ekosistem üzerindeki etkisinde ne kadar önemli olduğunu azımsıyorsunuz gibi
      Tipler, implement ettikleri interface’leri önceden bildirmek zorunda olsaydı Go bambaşka bir dil olurdu. Bu Go’nun başlıca ayırt edici özelliklerinden biriydi. En azından TypeScript, başka nedenlerle yapısal tip interface’lerini ortaya koyana kadar öyleydi
    • Yapısal tipler zaten 25 yıldan da eski bir kavram ve OCaml ile Scala gibi dillerde de kullanılıyordu
    • Bunun nasıl bir yenilik olduğunu anlamıyorum. Go’dan önceki aklıma gelen tüm ana akım diller bu şekilde çalışıyor
      Bir interface tanımladığınızda, o interface’in implementasyonunu mutlaka sağlamaya zorlayan, önemseyeceğimiz tek bir programlama dili sayabilir misiniz?
  • Go’nun kriptografiyle ilgili sorunları sanırım hâlâ pek fazla dile getirilmiyor. OpenSSH SHA1’i kullanımdan kaldırdıktan sonra Go ekibinin x/crypto/sshe SHA2 desteği eklemesi tam 1 yıl sürdü [1]. Gitea bunun bilinen mağdurlarındandı [2]
    Üstelik kriptografi bakım sorumlusunun GnuPG’ye saldırması [3] ve Dan Bernstein’ın güvenilirliğini zedelemeye çalışır görünmesi [4] güven vermiyor
    [1]: https://github.com/golang/go/issues/49269
    [2]: https://github.com/go-gitea/gitea/issues/17798
    [3]: https://twitter.com/FiloSottile/status/1127643698676797441
    [4]: https://twitter.com/FiloSottile/status/1555669786826244096

    • Sorun şu ki x/ paketleri çoğu zaman ihmal ediliyor ve yeni katkı verenlerin yamalarını başarıyla göndermesini zorlaştıran bir geliştirme modelini izliyor
      Buna karşılık standart kütüphanedeki crypto paketinin Go’nun büyük başarılarından biri olduğunu düşünüyorum. OpenSSL uzun süre tam bir felaketti; Go ve özellikle agl çok yaygın kullanılan alternatif bir uygulama geliştirdi ve dağıttı, ortalama kalitesi de yüksekti. Bu özellikle herkese açık API’de ayağa sıkma ihtimalinin çok daha az olması açısından geçerli
  • Bu yazı gofmti “doğru yapılan şeylerden” biri olarak anıyor; özellikle vurgulanmayı hak ediyor
    Birçok dil tasarımcısı ve savunucusu için önemsiz görünebilir, ama Go projesinin ilk gününden itibaren yaygın bir bisiklet kulübesi tartışmasını tamamen ortadan kaldırdığı için muazzam değer sağlıyor
    Daha yeni dillerden birkaçının bunu bilinçli olarak kopyaladığını ya da “Go’da da var, bizim de yapmamız gerek” diye düşünüp benimsediğini gördüm
    Epey tuhaf biçimlendirme kuralları da gördüm, ama alışamayacağım kural neredeyse hiç olmadı. Buna karşılık zorunlu biçimlendirme kuralı olmayan kod tabanlarında, bunun sonucu olarak kodu anlamanın çoğu kez daha zorlaştığını gördüm

    • Kod biçimlendirmesiyle oynama eğilimim var; go fmtnin bunu büyük ölçüde anlamsız hale getirmesini seviyorum
  • “21. yüzyıl sunucu kodu yazmak için gerekenlerin çoğunu barındıran sağlam ve iyi yapılmış bir kütüphanenin varlığı büyük bir varlıktı” sözüne katılıyorum
    Go, Google’ın bir sorunu olduğu için Google tarafından finanse edildi. Sunucu tarafı uygulama kodunu çok yazmaları gerekiyordu; Python fazla yavaştı, C++ ise fazla kırılgandı. Go bu boşluğa çok iyi oturdu
    Büyük bir artısı da Google’daki insanların bu işler için gereken kütüphaneleri yazmış ve bunları içeride de kullanıyor olmasıydı. Bu yüzden kütüphaneleri kullandığınızda, hata yolları bile büyük ölçüde gerçekten üzerinden geçilmiş kodlardı
    Dil konusunda teknik görüş ayrılıklarım var. Özellikle başlangıçta her şey için kuyruk kullanmaya yapılan vurgu, hatta kuyrukla mutex oluşturulan kısım böyleydi. Ama kullanım senaryosuna uygun green thread meselesini doğru yakaladılar. Fonksiyon rengi problemi gerçek bir sorun ve Rust’ta async ile thread’leri birlikte kullanmayı sağlayan anlaşılması güç numaralar fazla abartılı. Go biraz performanstan vazgeçip büyük bir basitlik kazanıyor
    Eski thread nefretinin ilginç bir yanı da var. UNIVAC mainframe ile başladım; 1967’den beri thread’ler vardı ve o zaman bunlara “activities” deniyordu. 1972’de yalnızca kullanıcı uzayı thread’leri yoktu, bunlar simetrik çok işlemcilerde de çalışıyordu. Asenkron G/Ç ve kullanıcı uzayı tamamlama fonksiyonları, kilitler için yerleşik komutlar, içeriden thread’li bir işletim sistemi de vardı
    Thread’leri ve çok işlemcileri normal şeyler olarak görüyorduk; UNIX’e geçince bunları kaybetmişiz gibi geldi. UNIX/Linux’un bu alanda yetişmesi onlarca yıl aldı ve birkaç nesil programcı paylaşımlı bellekli çok işlemcileri kullanmayı bilmedi
    Dijkstra’nın erken dönem eşzamanlılık teorisi başka terimlerle ve çoğu zaman daha kötü tasarımlarla yeniden icat edildi. Go ekibi, Dijkstra’nın bounded buffer’ını ve uzunluğu 0 ve 1 olan bounded buffer’ların neden faydalı olduğunu anladı. Bunu yeniden görmek güzeldi. Doğru ilkel işlemler varsa eşzamanlılık o kadar da zor değildir. Klasik pthreads tarzı düşüncede olduğu gibi her yere kilit serpiştirerek çözmeye çalışırsanız düzgün çalışmaz. UNIX/Linux’un ilk dönemlerinde CPU scheduler’ın gerçekten berbat olması ve thread engelinin kaldırılmasının korkunç çalışması da yardımcı olmadı

    • Rastgele HN yorumcuları sık sık “Go, Google’ın bir sorunu olduğu için finanse edildi” gibi şeyler söylüyor; bu, Google’ın nasıl işlediğini ya da ne kadar büyük bir şirket olduğunu pek bilmemelerinden kaynaklanıyor
      Go, Rob Pike’ın bir sorunu olduğu için yapıldı. C++, Java ve Python’dan hoşlanmıyordu; Rob Pike olduğu için de Google birkaç yıl boyunca yeni bir dil üzerinde çalışmasına izin verdi. Larry, Sergey, Sundar ya da Eric, Rob’un yanına gidip ondan bir şey yapmasını istemedi
      Genel olarak Go, Rob Pike destek istediği, Google Rob Pike’ı elde tutmak istediği ve neredeyse kesin olarak ilginç bir şey yapacağını düşündüğü için finanse edildi. Google Engineering’de şirket parası fiilen insanların bir şey üzerinde çalışmasına izin vermek gibi bir anlama gelir
      Rob Pike çok iyi bir mühendis olduğu için Go bazı açılardan epey iyi çıktı ve Google operasyonel uygulamaları yazmak için C++, Python, Java kullanmak zorunda kalmasına dair başlangıçtaki sorununa iyi uydu. Google içinde bazı kişiler de buna katıldı ve Go kullanmaya başladı; aralarındaki etkili kişiler de başkalarını Python yerine Go kullanmaya “teşvik etti”
    • Go yalnızca bir Google projesi değil; aslında Unix/Linux için Plan 9’un derleyici felsefesi ve CSP’sidir
    • Bu, o dönemde Google’da çalıştığıma dair hatırladıklarımla uyuşmuyor. “Go sistem programlama içindi” mem’i gibi, yakından bakınca pek mantıklı gelmeyen bir inanca daha yakın
      2009’da Google’da Python, YouTube satın alması örneği dışında, birkaç dahili yardımcı araç haricindeki sunucularda neredeyse kullanılmıyordu; dolayısıyla bu fikri hemen eleyebiliriz. Google’ın kendi yaptığı en büyük Python sunucusu, Guido van Rossum’un yazdığı kod inceleme aracı Mondrian’dı; daha sonra Java ile yazılmış Critique onun yerini aldı
      O dönemde Google, programlama dili kavgalarını ortadan kaldırmak için oldukça sıkı bir üç dil politikasına sahipti. C++, Java ve Python kullanılabiliyordu; Python betikler için, C++ altyapı için, Java ise web sunucuları için kullanılıyordu
      Örtüşen alanlar da vardı. Java, C++’tan daha geç benimsenmişti ve bazı web sunucuları yeniden yazılması zor olduğu için C++ olarak kalmıştı. Java’ya kademeli geçiş denemeleri de vardı ama pek tutunmadı. Megastore gibi bazı altyapı sunucuları Java ile yazılmıştı; çekirdek kütüphaneler ise genellikle C++ olup JNI ve Python binding’leriyle geliyordu
      Politikada boşluklar da vardı; bazı ekipler dahili altyapı için kendi dillerini oluşturdu ve gerçek kod tabanında özel yapılandırma dilleriyle Rob Pike’ın yaptığı Sawzall da kullanılıyordu. Sözdizimi Go’ya biraz benziyordu
      Genel olarak insanlar oldukça fazla seçim özgürlüğüne sahipti; yeni web sunucuları çoğunlukla Java ile, yeni veritabanı motorları gibi şeyler ise çoğunlukla C++ ile yazılıyordu
      Asenkron kod yazmak kesinlikle zordu ve Go’nun bu kısmı doğru çözdüğü de doğru. Ama Go, Google’ın sorununu çözmek için üst yönetimin başlattığı bir proje değildi. Yönetim böyle projelerden korktuğu için değil; geliştirici sıkıntılarını doğrudan çözmek amacıyla ilgili ekiplerin yaptığı ve insan kaynağı ayırdığı çok sayıda dahili altyapı projesi vardı. O dönemde yürütülen büyük ölçekli ağ yükseltmeleri buna örnekti. Bu tür projeler önceden duyurulurdu
      Bu durumdan büyük bir memnuniyetsizlik olduğunu hatırlamıyorum. Derleme süreleri, Bazel/Blaze uzak derleme kümeleriyle çalışana kadar sorundu; ondan sonra her şey uzaktan cache’lendiği için devasa kod tabanları bile birkaç saniyede derlenebiliyordu. Yerel derleyici hızı neredeyse önemsiz hale geldi ve javac da çok hızlıydı
      Go’nun duyurulması oldukça şaşırtıcıydı. Gerçekten Google’ın sorununu çözmek için geliştirilmiş olsaydı, önce içeride yayınlamak, dahili kullanıcılarla birkaç yıl geliştirmek ve sonra halka açmak tipik Google yöntemi olurdu. Ama Go önce herkese açıklandı. Çevremdeki insanlar bunun ne için olduğunu merak ediyordu; gerçekten dahili talep tarafından yönlendirilmiş olsaydı beklenmeyecek bir tepkiydi
  • Ken Thompson’ın C derleyicisini LLVM yerine kullanma kararıyla ilgili bölüm ilginç. İnsanlar şikâyet etmişti; özellikle ilk sürümlerde üretilen kodun daha az optimize olmasına da yol açmıştı.
    Bunun karşılığında bölünmüş yığınları hızlıca yapabildiler. Bunu LLVM’de uygulayıp LLVM ABI’sine uydurmak zorunda kalsalardı belki hiç yapamayacaklardı.
    Yazıda bu, kararın tek faydası olarak değil, faydalardan birine örnek olarak verilmiş.

    • Röportajdaki LLVM’le ilgili kısım doğru değil. Rust için LLVM ile bölünmüş yığın uygulamıştım; aslında oldukça kolaydı.
      X86FrameLowering’de zaten destek vardı ve Go yayımlandığı sırada da mevcuttu. Yığın bölmeyi açınca LLVM, fonksiyon prologue’unda bir kontrol üretir ve gerekirse daha fazla yığın ayırmak için __morestack çağırır. Windows MSVC ABI’si de _chkstk desteği için çok benzer koda ihtiyaç duyduğundan, __morestack desteğiyle doğal biçimde örtüşüyordu.
      Asıl zor olan, GDB’nin bölünmüş yığınları anlamasını sağlamaktı; bu, derleyici uygulamasının herhangi bir kısmından daha zordu. Bu da backend’den bağımsızdır.
      Yazarın muhtemelen karıştırdığı şey, taşınabilir/yeniden konumlandırılabilir yığınlardır. O dönemde hassas çöp toplama gerektiği için uygulaması zordu, ama şimdi Azul bunu LLVM’de uyguladı. O zaman hassas çöp toplamayı uygulamanın en kolay yolu, fonksiyon çağrıları boyunca tüm register’ları spill etmekti; bu daha fazla uygulama çabası gerektirse de aşırı bir iş değildi. Plan 9 derleyicisi zaten bunu yapıyor gibi göründüğünden, 6g/8g’ye kıyasla bir performans gerilemesi de olmazdı. Her hâlükârda Azul’un çöp toplama desteği artık kökleri register’larda saklayabilen düzgün bir uygulamaya sahip.
    • Sonuçta Go bölünmüş yığınlardan uzaklaşmadı mı? 2014’te çıkan Go 1.3’teydi. Sebep “hot spot” sorunuydu [1].
      Bu yüzden deney yapabilme yeteneğinin değerli olduğu doğru, ama bu belirli örnek kusursuz bir vaka değil.
      [1]: https://go.dev/doc/go1.3#:~:text=Go%201.3%20has%20changed%20...
  • Statik tipli bir hobi dili tasarlarken interface’ler ile generics’i birlikte ele alan bir şey deniyorum ve Rob’un haklı olduğunu bizzat hissediyorum. İkisini iyi biçimde uyumlu hâle getirmek gerçekten zor.
    Yine de buna değer olduğunu düşünüyorum. Şahsen, kullanıcıların kendi generic tiplerini tanımlayamadığı statik tipli bir dili kullanmak pek tatmin edici olmazdı.
    Eskiden BASIC’te alt yordamlar için GOSUB vardı ama argüman alan alt yordam yazmanın yolu olmayan bir ortamda programlama yapmıştım. Bu deneyimi tip sistemi düzeyinde tekrarlamak istemem.
    Bu yüzden Go ekibinin iyi bir tasarım bulmasının uzun sürmesini anlayabiliyorum. İyi bir dil tasarlamak zordur; tip sistemi olan iyi bir dil tasarlamak 10 kat daha zordur; generics içeren bir tip sistemi tasarlamak ise bunun da 10 kat daha zordur.

    • Katılmıyorum. Generics uygulamasındaki en zor kısım, implementation inheritance desteklendiğinde ortaya çıkar; Go ise bunu desteklemiyor.
      Go, generics uygulamasında en kolay işi üstlenmiş sayılır. Bunu yapmamalarının nedeni teknik değildi. İdeolojikti ve tamamen cehalete dayanıyordu; çünkü Go tasarımcılarının çoğu 90’ların sonlarından sonra programlama dili teorisi alanını takip etmeyi bırakmıştı.
    • ML ailesi ve fonksiyonel dillerde bu sorun yok gibi görünüyor; bunların birçoğu Go’dan çok daha sofistike ve güçlü tip sistemlerine sahip.
    • Scala, Golang’den önce yayımlandı ve Golang çıktığında zaten popülerlik kazanıyordu. Arkasında GOOG ölçeğinde kaynaklar da yoktu.