2 puan yazan GN⁺ 2023-08-15 | 1 yorum | WhatsApp'ta paylaş
  • Go 1.21, yeni toolchain'in geçmiş Go sürümlerinin davranışlarını da mümkün olduğunca kararlı biçimde uygulamasını sağlamak için GODEBUG tabanlı uyumluluğu genişleterek yükseltme yükünü azaltmaya odaklanıyor
  • Go, 2012’de Go 1’den beri kaynak uyumluluğu sözü veriyor; herkese açık API denetimi ve geniş ölçekli dahili testlerle kaldırma ve değişikliklerden doğan kırılmaları azaltıyor
  • time.Now hassasiyetinin artırılması, sort uygulamasının değişmesi, compress/flate çıktısının değişmesi, strconv.ParseInt girdilerinin genişlemesi ve net.ParseIP ayrıştırmasının değişmesi gibi belgelerce izin verilen iyileştirmeler bile mevcut programları bozabiliyor
  • Go 1.21’den itibaren uyumluluk amaçlı GODEBUG ayarları en az 2 yıl veya 4 Go sürümü boyunca korunuyor ve go.mod içindeki go sürümüne göre önceki davranış varsayılan olarak korunabiliyor
  • Go 2, Go 1 programlarını bozan yeni bir spesifikasyon olarak gelmeyecek; Go, yeni özellikler eklese bile uyumluluğa öncelik vererek toolchain yükseltmelerini kararlı tutuyor

Go 1 uyumluluğunun temel ilkesi

  • Go, 2012’de Go 1 ile birlikte yayımlanan “Go 1 and the Future of Go Programs” belgesinde, Go 1 spesifikasyonuna uyan programların bu spesifikasyonun ömrü boyunca değişmeden derlenmeye ve doğru çalışmaya devam etmesini hedeflediğini ortaya koydu
  • Bu sözün merkezinde kaynak uyumluluğu yer alıyor
    • Yeni bir Go sürümüne güncellerken kodun yeniden derlenmesi gerekiyor
    • Yeni API’ler eklenebilir, ancak mevcut kodu bozacak biçimde ekleme yapmaktan kaçınılmalı
  • Gelecekteki hiçbir değişikliğin hiçbir programı asla bozmayacağı garanti edilemez
    • Program bir hatalı davranışa bağımlıysa, o hata düzeltildiğinde program bozulabilir
    • Go, kırılmayı mümkün olduğunca azaltırken kararlı yükseltmeleri sürdürmeye çalışıyor

Herkese açık API denetimiyle uyumluluğu bozmayı engellemek

  • Go geliştirme sürecinde her paketin herkese açık API listesi, gerçek paketten ayrı dosyalarda tutuluyor
    • Örneğin go/api/go1.21.txt içinde bytes, cmp, context gibi paketlerin fonksiyon, metod ve tip girdileri kayıtlı
  • Standart testler, gerçek paket API’lerinin bu dosyalarla eşleşip eşleşmediğini kontrol ediyor
    • Yeni bir API eklendiğinde API dosyasına da eklenmeli ki test geçsin
    • Mevcut bir API değiştirilir ya da kaldırılırsa test başarısız olur
  • Yalnızca API kaldırmak değil, tip değiştirmek de uyumluluğu bozabilir
    • os.Stdout, *os.File tipinde global bir değişkendir
    • Bunu aynı metodlara sahip bir interface ile değiştirmek, greet(f *os.File) gibi *os.File bekleyen kodları bozar
  • API denetimi, API değişikliklerini ve kaldırmalarını yakalamakta yararlıdır; ancak Go’da ortaya çıkabilecek tüm uyumsuz değişiklikleri engellemez

Testlerin ortaya çıkardığı ince kırılmalar

  • Yeni Go sürümünün geliştirme sürümleri, Google içindeki tüm Go kod tabanında sürekli test edilir
    • Testler geçerse ilgili commit, Google’ın üretimdeki Go toolchain’ine kurulur
    • Dahili testler bozulursa bunun dış kodları da bozabileceği düşünülür ve etkiyi azaltmanın yolu aranır
  • Çoğu durumda değişiklik geri alınır ya da programları bozmayacak şekilde yeniden yazılır
  • Bazı değişiklikler ise programları bozsa bile önemli kabul edilip belgeler açısından uyumlu değişiklik olarak kalabilir
    • Bu durumda da etki alanı azaltılır ve olası sorunlar sürüm notlarına eklenir

Go 1.1’de ortaya çıkan iki örnek

  • Struct literal ve yeni alan

    • Go 1’de net.TCPAddr, IP ve Port alanlarına sahip bir struct’tı ve alan adı yazılmayan bileşik literal’ler de derleniyordu
    • Go 1.1’de net.TCPAddr yapısına Zone alanı eklenince mevcut kod “too few initializers in struct literal” hatasıyla artık derlenemez oldu
    • Uyumlu yazım biçimi, alan adları belirtilmiş literal kullanmaktır
var myAddr = &net.TCPAddr{
    IP: net.IPv4(18, 26, 4, 9),
    Port: 80,
}
  • Zone belirtilmezse bu alan zero value olan boş string’i kullanır
  • Standart kütüphane struct’ları için alan adlı bileşik literal kullanma gerekliliği uyumluluk belgesinde yer alır ve go vet, sonraki sürümlerle uyumluluk için sorun yaratabilecek alan adı içermeyen literal’leri raporlar
  • Zaman hassasiyeti

    • Go 1’den sonra time.Now, mikrosaniye hassasiyeti yerine nanosaniye hassasiyeti döndürecek şekilde değiştirildi
    • Bu değişiklik, time.Now değerini save ve load ile ileri geri taşıdıktan sonra aynı olmasını bekleyen testleri bozabiliyordu
    • Saklama gösterimi yalnızca mikrosaniye hassasiyetini koruyorsa test Go 1’de geçerken Go 1.1’de başarısız olabiliyordu
    • Go, bu tür testlerin düzeltilmesine yardımcı olmak için Round ve Truncate metodlarını ekledi ve sürüm notlarında olası sorunu ve yeni metodları anlattı
    • Artan hassasiyet daha iyi bir davranıştı ve fonksiyonun belgelenmiş kapsamı içinde izin verildiği için, bazı programları bozsa da yayımlandı

Uyumluluğu bozabilecek üç değişiklik türü

  • Çıktı değişikliği

    • Çıktı değişikliği, bir fonksiyonun öncekinden farklı çıktı üretmesi ama yeni çıktının önceki kadar doğru ya da daha doğru olması durumunda ortaya çıkar
    • time.Now için nanosaniye hassasiyeti eklenmesi bunun tipik örneğidir
    • Go 1.6’da sort uygulaması yaklaşık %10 hızlandırıldı ve bu sırada aynı değer sayılan öğelerin sırası değişti
    • Go 1.5 çıktısı: [red blue green white black yellow orange indigo violet]
    • Go 1.6 çıktısı: [red blue white green black orange yellow indigo violet]
    • Sıralama, aynı sonucu hangi sırayla döndürürse döndürsün kabul edilir; ancak belirli bir sırayı bekleyen programlar bozulabilir
    • Go 1.8’de compress/flate, benzer CPU ve bellek ek yüküyle daha küçük çıktı üretmek üzere iyileştirildi
    • Bu yüzden Google içindeki yeniden üretilebilir arşiv derlemeleri, mevcut arşivleri birebir yeniden üretemez hale geldi
    • İlgili proje, önceki algoritmayı korumak için compress/flate ve compress/gzip paketlerini fork etti
    • Çıktı değişikliklerine karşı programları ve testleri, tüm geçerli çıktıları kabul edecek şekilde yazmak daha iyidir
    • Gerçekten yeniden üretilebilir çıktı gerekiyorsa kod fork edilebilir, ancak bu da hata düzeltmelerinden kopmak anlamına gelir
  • Girdi değişikliği

    • Girdi değişikliği, bir fonksiyonun kabul ettiği girdiyi ya da bunu işleme biçimini değiştirdiğinde ortaya çıkar
    • Go 1.13, sayı okunabilirliği için alt çizgi sözdizimi ekledi ve strconv.ParseInt de bu yeni sözdizimini kabul edecek şekilde değişti
    • Alt çizgiyle ayrılmış sayıları ayrı bir veri biçimi olarak kullanan harici kullanıcıların kodu bu yüzden bozuldu
    • Bu kod önce ParseInt deniyor, yalnızca başarısız olursa alt çizgi işleme mantığına geçiyordu; fakat ParseInt artık başarısız olmuyordu
    • net.ParseIP, ilk IP RFC örneklerini izleyerek başında sıfır olan ondalık IP adreslerini kabul ediyordu
    • Go, 18.032.4.011 ifadesini 18.32.4.11 olarak okuyordu
    • BSD ailesindeki C kütüphaneleri ise baştaki sıfırı sekizlik sayı başlangıcı sayarak aynı string’i 18.26.4.9 olarak yorumluyordu
    • Go 1.17, net.ParseIP’nin başında sıfır olan değerleri tamamen reddedecek şekilde değiştirildi
    • Bu tercih, hem Go hem C bir IP adresini başarıyla ayrıştırdığında aynı anlama gelmesini sağlamak içindi
    • Kubernetes, mevcut kayıtlı yapılandırmaların Go 1.17’de ayrıştırılamama ihtimalinden endişe etti ve özgün net.ParseIP davranışının fork’unu kullanmaya başladı
    • Kullanıcı girdisi için, değeri ayrıştırmadan önce hangi sözdiziminin kabul edileceğini doğrulamak iyi bir yaklaşımdır; ancak bazı durumlarda kod fork etmek gerekebilir
  • Protokol değişikliği

    • Protokol değişikliği, bir paketteki değişikliğin dış dünyayla iletişimde kullanılan protokole görünür şekilde yansıdığı durumdur
    • Go 1.6, HTTP/2 için otomatik destek ekledi
    • Go 1.5 istemcileri yalnızca HTTP/1.1 kullandığı için belirli ağ ara cihazı ortamlarında sorunsuz çalışabiliyordu
    • Go 1.6’ya güncellendiğinde HTTP/2 kullanılmaya başlanıyor ve bu ortamda HTTP/2 çalışmıyorsa program bozulabiliyordu
    • Go, modern protokolleri varsayılan olarak desteklemek istiyor; ancak HTTP/2’yi etkinleştirmek, programda ya da Go’nun kendisinde bir hata olmasa bile programı bozabilir
    • Go 1.6, bu değişikliği sürüm notlarında belgeledi ve HTTP/2’yi devre dışı bırakma yolları sundu
    • TLSNextProto alanını açıkça ayarlamak
    • GODEBUG=http2client=0, GODEBUG=http2server=0 ya da ikisini birlikte ayarlamak
    • SHA1 tabanlı HTTPS sertifikası desteği de daha ince bir protokol değişikliği örneğidir
    • Sertifika otoriteleri 2015’te SHA1 sertifikası vermeyi bıraktı ve büyük tarayıcılar 2017’de bunları kabul etmeyi bıraktı
    • Go 1.18, SHA1 sertifika desteğini varsayılan olarak devre dışı bıraktı ve GODEBUG ile geçici çözüm sundu
    • Bazı Kubernetes kurulumları özel SHA1 sertifikaları kullanmayı sürdürdüğü için Go, bu geçici çözümü planlanandan daha uzun süre tutmaya karar verdi

Go 1.21’de genişletilmiş GODEBUG desteği

  • Go 1.21, ince uyumluluk sorunlarını da azaltmak için GODEBUG kullanımını genişletip resmileştiriyor
  • Go 1 uyumluluk kuralları çerçevesinde izin verilen ama mevcut programları bozabilecek değişiklikler için, tek tek programların yeni davranışı reddedebilmesini sağlayan GODEBUG ayarları tanımlanıyor
    • Ayar eklemenin mümkün olmadığı durumlar olabilir, ancak bunlar çok nadir görülmesi beklenen istisnalardır
  • Uyumluluk amaçlı GODEBUG ayarları en az 2 yıl, yani 4 Go sürümü boyunca korunur
    • http2client, http2server gibi ayarlar çok daha uzun, bazı durumlarda süresiz olarak korunabilir
  • Mümkün olduğunda her GODEBUG ayarına bir runtime/metrics sayacı bağlanır
    • Sayaç adı /godebug/non-default-behavior/<name>:events biçimindedir
    • Örneğin GODEBUG=http2client=0 ayarlanırsa /godebug/non-default-behavior/http2client:events, HTTP/2 olmadan yapılandırılmış HTTP transport sayısını sayar
  • Programın varsayılan GODEBUG değerleri, ana paketin go.mod dosyasındaki Go sürümüne göre belirlenir
    • go.mod içinde go 1.20 yazıyorsa ve Go 1.21 toolchain’ine geçilirse, Go 1.21’de değişen GODEBUG kontrollü davranışlar go.mod içeriği go 1.21 yapılana kadar Go 1.20 davranışını korur
  • Tek tek GODEBUG ayarları, package main içindeki //go:debug satırıyla değiştirilebilir
  • Tüm GODEBUG ayarları merkezi listede belgelenmiştir

panic(nil) örneği

  • Go 1.21’de panic(nil) artık nil olmayan bir runtime panic oluşturur
  • Bu değişiklik sayesinde recover sonucunun mevcut goroutine’in panic durumunda olup olmadığını güvenilir biçimde göstermesi sağlanır
  • Yeni davranış, GODEBUG ayarıyla kontrol edilir ve ana paketin go.mod dosyasındaki go satırına göre değişir
    • go 1.20 veya altındaysa panic(nil) kullanılmaya devam edilebilir
    • go 1.21 veya üzerindeyse panic(nil), runtime.PanicNilError içeren bir panic’e dönüşür
  • Sürüme bağlı bu varsayılan, package main içine şu satır eklenerek açıkça geçersiz kılınabilir
//go:debug panicnil=1
  • Bu kombinasyon, yeni toolchain’e yükseltirken önceki toolchain davranışını korumayı, yalnızca gerekli ayarları ince ayarla kontrol etmeyi ve üretim izlemeyle varsayılan dışı davranış kullanımını görmeyi mümkün kılar
  • Ayrıntılar “Go, Backwards Compatibility, and GODEBUG” belgesinde anlatılıyor

Go 2, Go 1’i bozmayacak

  • “Go 1 and the Future of Go Programs” belgesinde bir gün Go 2 spesifikasyonunun gelebileceğine dair bir not vardı
  • Go 1 programlarını artık derlemeyen anlamda bir Go 2 gelmeyecek
  • 2017’de başlayan, Go 1’in büyük revizyonu anlamındaki Go 2 ise fiilen zaten yaşandı
  • Go, geçmişle kopuştan ziyade uyumluluğun çok daha değerli olduğuna karar verdi ve uyumluluğu daha da güçlendiren bir yön seçti
  • Bundan sonra da yeni ve ilginç çalışmalar sürecek, ancak toolchain’ler arası yükseltmelerin mümkün olduğunca kararlı kalması için değişiklikler dikkatli ve uyumlu biçimde yapılacak

1 yorum

 
GN⁺ 2023-08-15
Hacker News yorumları
  • Uyumlulukta önemli soru “yapacak mıyız” değil, “nasıl yapacağız”dır. Aslında geriye dönük uyumluluktan çok, bundan sonra kodumun olduğu gibi çalışmaya devam etmesini istemeye daha yakın
    Go 1.21, diğer dil ekosistemlerinde aynı anda görülmesi zor iki temel şey sunuyor: her değişiklik için bir GODEBUG ayarı var, değişiklik bazında geri alınabiliyor ve eski uygulamanın kullanılıp kullanılmadığını algılayan metrikler de var. Ayrıca modül bazında araç zinciri sürümü var; daha eski Go ve daha yeni Go araç zincirleri, modül gibi güvenli biçimde otomatik olarak getirilebiliyor
    Bonus olarak go 1.21.2 gibi belirli bir sürüm belirtirseniz, daha yeni Go’da çalıştırılsa bile yeni davranışı açıkça istemeden önce ilgili opt-out yapılandırmalarını otomatik olarak uygular. Bunu kodda, go.mod içinde ya da ortam değişkenlerinde ilan edebilmek; geliştiricilerden dağıtım yapanlara kadar neredeyse tüm uyumluluk kullanım senaryolarını kapsayan sade ve güzel bir yol

    • Perl’de de benzer şekilde dosyanın en başına use v5.24 yazarsanız Perl 5.24 gibi davranmasını sağlayabilirsiniz; bu modül düzeyinde değil, dosya düzeyinde uygulanır
    • Üzgünüm ama ekip sayısı yeterince fazlaysa ve kod 1 milyon–10 milyon satırın üzerindeyse bu yaklaşım kulağa kâbus gibi geliyor
      Yeni sürümü destekleyip desteklemediğiniz bile başlı başına akıl almaz derecede karmaşık bir sorun yaratırken, “biz yeni sürümü desteklediğimizi düşünüyoruz, yeni sürüm de bizi desteklediğini düşünüyor ama birbirimizi kaçırıyoruz” şeklinde derin bir uçurum oluşuyor
    • Bu tür özellikler başka ana akım dillerde de kesinlikle var. Haskell daha da ileri gidip tek tek dosyalarda dil özelliklerini açıp kapatabiliyor
    • “Diğer dil ekosistemlerinde olmayan temel özellikler” deyip başka dillerde yaygın olan özellikleri sıralamak, en az hevesli Go kullanıcısı gibi görünmenize yol açıyor
  • Bu yön gerçekten çok iyi. Bir Go kod tabanına girip yalnızca Go sürümünü yükseltince her şeyin düzgün çalışacağını bekleyebilmekten daha iyi bir şey yok
    Yine de tip sisteminin, “bu artık hatalı kod, dolayısıyla derlenmiyor” türünden kırıcı değişiklikler olmadan büyük ölçüde iyileştirilmesinin zor olmasından endişeliyim. Go ekibinin böyle şeylerle ilgilenip ilgilenmediğini bilmiyorum ama dil özelliği eklemeden bile derleme zamanındaki sağlamlığı ciddi biçimde artırabilecek kolay kazanımlar çok
    Örneğin denetlenmemiş nil raporlama, dizi erişim denetimi, iç içe struct literal’larında tip çıkarımı, enum kapsamlılık denetimi gibi şeyler. Özellikle iç içe gRPC çağrıları yazarken yalnızca bir seviye tip çıkarımı gerekiyor; çağrılan fonksiyon imzasında tip zaten bulunduğu için Go’da bu çok acı verici

    • Go topluluğunun dışında aynı şeyi tekrar söylemek gerekirse, Rust veya Swift tarzı parametreli enum’lar gökten inmiş bir nimet gibi. Sayısız programı çok daha kolay yazılır hale getiriyor
      Go tip sistemi iyileştirilecekse, böyle sade ve güzel cebirsel veri tipleri eklenirse iyi olur. Go’ya da gerçekten çok yakışır; kendinize böyle bir hediye vermenizi dilerim
  • Tamamen katılıyorum. Go sürümlerini heyecanla beklememin nedeni, çoğu zaman hiçbir şeyi bozmadan faydalı şeyler eklemeleri
    Dilin hiçbir bölümü, geriye dönük uyumlu değişikliklerle düzeltilemeyecek kadar bozuk görünmüyor. Döngü değişkeni ataması gibi az sayıdaki tuzak için de genelde uyumluluğu koruyan öneriler var

    • C# da geriye dönük uyumluluğu tamamen koruyor, ama .NET geliştiricileri arasında tam tersi bir hava görüyorum. “Dil şişiyor”, “öğrenmesi zorlaşıyor” diyorlar
      Kişisel olarak Go sürümlerini bekleme bakış açısına katılıyorum, ama iki ekosistemin tutum farkı ilginç
    • Ben de iki kuruşumu ekleyeyim: Go yükseltmelerinde sık sık epey büyük kırılmalar yaşadım. Rust yükseltmelerinde veya gcc yükseltmelerinde çok daha az sorunla karşılaştım; C ve Rust derleyici güncellemeleri gerçekten geriye dönük uyumlu gibi hissettiriyor
      Daha önce yaşadığım kırılmaların bir kısmını derlemiştim: https://news.ycombinator.com/item?id=29763324
      Rust veya gcc’de derleyiciyi yükseltirken dil özellikleri kazanırsınız, ama karmaşık kütüphanelerin çoğu aynı kalır ve ayrı olarak yükseltilebilir. Örneğin Rust’ta HTTP hyper, C’de libcurl gibi ayrıdır
      Buna karşılık Go’da derleyiciyi yükselttiğinizde generics, embed, araç zinciri özelliklerinin yanı sıra tls, güvenlik kütüphaneleri ve HTTP istemcisi/sunucusu değişiklikleri de birlikte gelir. http, tls, crypto gibi büyük standart kütüphane parçaları ayrı kütüphaneler olsaydı çok daha iyi olurdu. O zaman derleyiciyi korkmadan yükseltip kütüphaneleri kendi hızımda yükseltebilirdim
    • Genel olarak katılıyorum ama geleceği bilemeyiz. Rust 2018 edition async anahtar sözcüğünü getirdi; 2015 edition’da async adında değişken veya fonksiyon oluşturulabildiği için bu kırıcı değişiklikti
      Geriye dönük uyumluluk iyidir, ama Go’nun uyumluluğu bozmamak uğruna gelecekte bir yenilik X’i yapamaması gerçekten kabul edilebilir mi, emin olmak zor
    • Sum type’lar ve hata işleme gevezeliğini azaltmanın daha iyi bir yolu olsa iyi olurdu
  • Gelecekteki Go 2’nin Go 1 uyumluluğunu kesinlikle bozmayacağı yönündeki tutumu güçlü biçimde destekliyorum. Dili o kadar büyük ölçüde değiştirmek gerekiyorsa, bence en iyisi fork edip adını değiştirmek olur
    Yine de neden daha ileri gidip “Go 2 olmayacak” diyerek belirsizliği ortadan kaldırmadıklarını merak ediyorum. Kuramsal bir Go 2 tüm Go 1 programlarını çalıştırıyorsa, Go 1.xx sürümlerinden hangi açıdan farklı olacak? Yazı “Go 1 programlarını bozan bir Go 2 olmayacak” diyor ama bundan ötesini söylemiyor gibi

    • 5 yıl önce zaten “öyle olacak” denmişti. Sadece “eğer” önkoşulu vardı
      https://github.com/golang/proposal/blob/d661ed19a203000b7c54...
      Yukarıdaki süreç planlandığı gibi işlerse, önemli bir anlamda Go 2’nin olmayacağı ve yeni dil özellikleri ile kütüphane özelliklerine yavaş yavaş geçileceği açıklanıyor. Bir noktada pazarlama açısından “artık Go 2” denebilir, ama tamamen atlanabilir de. Mantık şu: C 2.0 yoktu, Go 2.0’a neden ihtiyaç olsun?
      C, C++, Java gibi popüler diller de aslında hep 1.N sürümleri gibi ilerliyor; Go’nun da bunu izlemesi daha iyi olur diye düşünüyorum. Uyumsuz yeni bir dil ya da çekirdek kütüphane anlamında gerçek bir Go 2, kullanıcılar için iyi bir seçenek değil ve zararlı olabilir
    • Java bu yolu zaten yaşadı. Java 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7 vardı; sonra “nasıl olsa geriye dönük uyumluluğu bozmuyoruz, 1.x yerine Java 8, 9, 10…21 diyelim” şeklinde değişti
      Sonuçta bu yaklaşımın mantıklı olduğunu düşünüyorum
    • Kaynak uyumluluğunu bozmak için gereken değişiklik ölçeğini fazla abartıyor olabilirsiniz. Hafif bir örnek olarak anahtar sözcük eklemek var
      Topluluğun açıkça istediği yeni bir dil özelliği varsa ve bu özelliği eklemenin doğru ya da tek yolu yeni bir anahtar sözcükse, kaynak uyumluluğunu asla bozmama kuralı yüzünden o özellik sonsuza kadar eklenemez. Dil semantiğini değiştiren büyük değişiklikler konusunda katılıyorum, ama geriye dönük uyumsuz değişiklikler her zaman devasa değişiklikler değildir
    • Rust’ın edition sistemi iyi bir karşı örnek bence. Edition’lar arasındaki farklar kırıcı değişikliklerdir ama pratikte inanılmaz büyük değildir
      Teoride geriye dönük uyumluluğun asla değişmemesi fikri güzel, fakat gerçek dünyada anlamlı kırıcı değişiklikler de vardır. İlk tasarımda X ya da Y’nin hesaba katılmadığı dil özelliklerini sonsuza kadar taşımak her zaman kazanç gibi gelmiyor
    • Yazının sonunda zaten bunu söylüyor. Geçmişle bağları koparıp eski programları artık derlemeyen anlamda bir Go 2 asla olmayacak; 2017’de yönelmeye başlanan Go 1’in büyük revizyonu anlamında Go 2 ise zaten gerçekleşti diyor
  • Go’yu çok kullanıyorum ve bu yön gerçekten içimi ısıtıyor
    Uyumluluk, dil ekibi açısından pek eğlenceli olmayabilir. Çünkü her zaman bir ayağınızı “uzak geçmişte” sağlam tutmanız gerekir. Ama büyük Go sistemlerini sürdürmek zorunda olan biri için bu gerçekten büyük bir hediye

    • Birkaç yıl boyunca Go derleyicisi üzerinde çalıştım; o kadar büyük bir sorun değildi. Dikkatli düşündük ve pek çok fikri reddettik
      Doğru şekilde oturtamıyorsak, henüz doğru şey değildi; yeniden denedik. Yine uymuyorsa, muhtemelen sorunu yeterince anlamamıştık ve daha uzun süre olgunlaşmasına izin vermek doğruydu
      Dikkatli düşünen ve doğru fikirlerin içeri girmesi için çabalayan insanlarla çalışmak gerçekten güzeldi. Russ’ın BDFL rolünü üstlenmesine, Ian’la, Rob’la ve Rob’la çalışmaya minnettarım; bunun sayesinde çok daha iyi bir mühendis oldum
  • İlgili yazı: Forward Compatibility and Toolchain Management in Go 1.21 - https://news.ycombinator.com/item?id=37122932

  • “Sıkıcı iyidir. Sıkıcı olan kararlıdır. Sıkıcı olması, Go’da neyin değiştiğini dert etmeden kendi işinize odaklanabilmeniz demektir” cümlesi gerçekten çok etkileyici
    Asıl işimde NodeJS ve genel JS ekosistemini kullanıyorum; gerçekten çok zorlanıyorum. Ekosistem parçalı ve herkes kendi yöntemini izlediği için istikrarlı hale getirmek zor. Yine de bu işi hâlâ seviyorum, ama JS ekosisteminde de güvenip dayanabileceğimiz istikrarlı, modern bir temel olsa güzel olurdu

    • JS ekosistemi, örneğin npm ya da React tarafı için bu doğru olabilir. Ama bir dil olarak JavaScript’in, Go var olmadan önce bile geriye dönük uyumluluğu önceliklendirdiğini de kabul etmek gerekir
    • Go’nun neden hâlâ yeni Java/.NET olmadığını merak ediyorum
      Pek çok araç ve API Go ile yazıldı; hedef sistemde ayrı bir runtime gerektirmemesi de sıkça büyük bir avantaj olarak gösteriliyor. Dil de öğrenmesi ve kullanması basit görünüyor, VSC desteği ve GoLand iyi, hata işleme gibi yaygın şikâyetler de belirleyici kusurlar gibi durmuyor
      Önümüzdeki on yıllarda geliştirme dünyasının ana akımı olmak ya da en azından iş piyasasının büyük bir bölümünü kaplamak için Go’nun daha neye ihtiyacı var merak ediyorum. Çünkü bazı yerlerde hâlâ niş bir dil olarak görülüyor
    • JavaScript geriye dönük uyumluluğuyla ünlüdür. Tam da bu yüzden senin tarif ettiğin kaotik duruma gelmiştir
    • Artık gerçekten istikrarlı bir temel olduğunu düşünüyorum. ES modülleri ve ES2020 kodu hem Node hem de başlıca tarayıcılar tarafından destekleniyor. Node’da yerleşik bir test runner da var
      Sorun, herkesin bu taban çizgisine gelmesini sağlamak. Oraya varıldığında çok daha iyi olacak gibi
      Ayrıca JS ekosistemi frontend UI çalışmalarını da içeriyor ve kullanım alanı o kadar geniş ki birden fazla implementasyonun ortaya çıkması kaçınılmaz. Hatta bu istenir bir şey de olabilir
  • Python’dan Golang’e bazı kodları taşımak, ölçeklendirmede büyük yardım sağladı. Go’nun temel beyanı olan geriye dönük uyumluluğu korumayı sürdüreceği haberini görmek gerçekten sevindirici

  • IP ayrıştırmadan bahsediyoruz demek. Asıl BSD’nin inet_ntoa’sı acaba nasıl yazılmıştı, merak ediyorum
    atoi/atol ile %d/%u kullanan sscanf her zaman tam olarak 10 tabanlı tamsayı olarak ayrıştırdığına göre, böyle tuhaf bir etki üretmek için %i ya da 0 tabanlı strtou kullanmak gerekmiş olmalı

    • Tahmin etmeye gerek yok. Benim inet_aton kılavuz sayfam bunun 4.3BSD’den geldiğini söylüyor: https://github.com/dank101/4.3BSD-Reno/blob/master/lib/libc/...
      Daha eski 4.2BSD’deki inet_addr da aynı mantığı kullanıyor: https://github.com/dank101/4.2BSD/blob/master/lib/libc/inet/...
      inet_aton ve inet_addr, adresi en doğal yolla ayrıştırıyor. strtoul ya da özellikle sscanf gibi bir şey kullanmak garip olurdu. C işaretçilerinin güzelliği, basit ayrıştırma işlerini çok kolaylaştırmasında; hatta belki de fazla kolaylaştırmasında
    • O kısmı okuyunca güldüm. Eskiden /etc/hosts dosyasını “düzenlemek” için her okteti 0 ile doldurmuştum
      Sonuçta geri dönüp 0’ları kaldırmam gerekti
  • Bir dil tasarımcısı olarak, gerçek bir Go 2 yapmama kararı da dahil burada alınan kararları takdir ediyorum
    Ben de uyumluluğu garanti etmek için kullanılan teknikleri alıp kullanmayı düşünüyorum