2 puan yazan GN⁺ 2023-10-31 | 1 yorum | WhatsApp'ta paylaş
  • Uzun geliştirme deneyimlerinde tekrar tekrar ortaya çıkan en büyük ders, karmaşıklığın kod tabanının “ebedi düşmanı” olduğu ve küçük bir değişikliğin alakasız yerleri bozabildiği bir durum yarattığıdır
  • Karmaşıklığı azaltmanın en güçlü aracı, özelliklere ve soyutlamalara “hayır” demektir; ancak gerçekçi bir uzlaşma gerektiğinde 80/20 çözümü ile az kodla değerin çoğu sunulur
  • Tasarım ve test, çok erken soyutlama yapmaktansa sistemin şekli ortaya çıktıktan sonra iyi sınır noktaları bulmaya ağırlık verir ve birim testlerinden daha uzun ömürlü olan entegrasyon testlerini önemser
  • Araçlar, tip sistemi, loglama, debugger ve API tasarımı geliştiricinin bilişsel yükünü azaltmalıdır; tip sisteminin büyük pratik değeri ise IDE otomatik tamamlama özelliğinde yatar
  • DRY, concern separation, mikroservisler, SPA, generics ve aşırı refactoring gibi kulağa iyi gelen teknikler de kodun anlaşılmasını ve bakımını zorlaştırıyorsa karmaşıklığa açılan bir kapı haline gelir

Karmaşıklık kod tabanındaki en büyük risktir

  • Karmaşıklık, başlangıçta anlaşılabilir olan bir sistemi bir anda yönetilmesi zor hale getirir ve bir yerde yapılan değişiklik alakasız görünen başka yerleri bozabilir
  • Karmaşıklık, iyi niyetli geliştiriciler ya da proje yöneticileri aracılığıyla sisteme girebilir; bazen sorunun kaynağı bizzat kendi eklediğiniz karmaşıklık olur
  • Karmaşıklığı çözen sihirli bir “sopa” yoktur; en iyi yaklaşım, onu baştan içeri almamaktır

“hayır” ve “tamam”: reddetmek ve gerçekçi uzlaşma

  • Karmaşıklığı engellemenin en iyi silahı “hayır” demektir
    • “O özelliği yapmıyoruz”
    • “O soyutlamayı kurmuyoruz”
  • Ancak “hayır”, iyi bir mühendislik tavsiyesi olsa da daha fazla ödül ya da terfi açısından dezavantajlı olabilir
  • Gerçekte uzlaşmak gerektiğinde cevap “tamam” olur ve sonra 80/20 solution aranır
    • İstenen değerin %80’ini kodun %20’siyle gerçekleştirme yaklaşımı
    • Tüm süs özelliklere sahip olmayabilir ve biraz çirkin görünebilir, ama değerin çoğunu sunarken karmaşıklığı düşük tutar
  • Proje yöneticileri ayrıntılı gereksinimleri unutabilir, değiştirebilir ya da işten ayrılabilir; bu yüzden bazen 80/20 yaklaşımı daha iyi seçim olur

Tasarım ve kodu bölmek çok erken yapılırsa risklidir

  • Projenin başında sistemin şekli henüz “su” gibi belirsizdir; bu yüzden çok erken parçalamadan kaçınılır
  • Zaman geçtikçe iyi sınır noktaları görünür hale gelir
    • Sistemin geri kalanıyla arayüzü dardır
    • Az sayıda fonksiyon veya soyutlama ile iç karmaşıklığı gizler
  • Soyutlamayı fazla erken kurmak, yanlış soyutlama üretmeye çok yatkındır; bu nedenle beklemek daha ağır basar
  • Başlangıçta büyük soyutlamalar kurmaya hevesli geliştiricilere UML gibi atılabilir çıktılar vermek ya da yarına çalışan bir demo istemek yardımcı olabilir
  • İlk prototipler, gerçekten çalışan kodu ve gerçekçi kısıtları daha hızlı gösterir

Test, “sonra topluca” değil “şekillenirken birlikte” yapılmalı

  • Testler birçok sorunu önler; ancak alanı bile anlamadan test first yaklaşımını zorlamaya karşı çıkılır
  • Prototipten sonra kod sağlamlaşmaya başladığında testlerin çoğunu yazmak tercih edilir
  • “Benim makinemde çalışıyor” deyip testleri atlamak çok kötü bir tutumdur
  • Test türleri arasında belirgin tercihler vardır
    • unit tests: Projenin başında faydalıdır ama implementasyon değişiklikleriyle kolay bozulabilir ve refactoring’i zorlaştırabilir
    • end to end: Tüm sistemin çalışmasını gösterir ama bozulduğunda nedenini anlamak zordur; sık bozulursa kolayca görmezden gelinir
    • integration tests: Sistemin doğruluğunu görecek kadar yukarıda, debugger ile nedeni bulacak kadar aşağıdadır; en iyi denge noktasına en yakındır
  • Sınır API’leri kararlı hale geldiğinde bunların etrafına entegrasyon testlerine güçlü yatırım yapılır
  • End-to-end testler, en yaygın UI işlevleri ve önemli bazı edge case’lere odaklanan küçük ve iyi yönetilen bir set olarak tutulur
  • mocking yalnızca gerçekten gerektiğinde, mümkünse büyük sınır noktaları seviyesinde kullanılır
  • Bir bug bulunduğunda istisna olarak önce onu regression test ile yeniden üretip sonra düzeltmek tercih edilir

Agile, refactoring ve Chesterton's Fence

  • Agile kendi başına en kötü şey değildir ve yazılım organizasyonunda kullanılabilecek bir yöntemdir; ama başarısızlığı mazur gösteren bir araç gibi davranan “agile shaman”lara karşı dikkatli olunmalıdır
  • Prototipleme, iyi araçlar ve iyi geliştirici işe alımı yazılım başarısı için daha önemlidir; hiçbir süreç tüm sorunları çözen bir silver bullet değildir
  • Refactoring özellikle projenin ilerleyen aşamalarında, kod sağlamlaştığında faydalıdır; ancak refactoring ne kadar büyükse başarısızlık ihtimali de o kadar yüksektir
    • Küçük parçalara bölünerek ilerlenir
    • Sistem mümkün olduğunca çalışır halde tutulur
    • Her adım tamamlandıktan sonra bir sonrakine geçilir
  • Aşırı soyutlama, refactoring başarısızlığına ve sistem arızasına yol açabilir
    • J2EE birçok projeye zarar vermiş bir örnektir
    • OSGi karmaşıklığı hapsetmeye çalışırken onu daha da güçlendirmiş ve yıllar düzeyinde yeniden çalışma gerektirmiştir
  • Chesterton's Fence, göze kötü görünen kodun neden var olduğunu anlamadan kaldırılmaması gerektiği fikriyle ilişkilidir
  • Çalışan koda, mükemmel olmasa da saygı gösterilmelidir; sistem ne kadar büyükse önce onu anlamak için o kadar çok zaman gerekir

Mikroservisler ve araçlar

  • Mikroservisler, sistemi doğru bölme gibi zor bir probleme bir de ağ çağrılarını ekler
  • Araçlar geliştiricinin üretkenliğini ve kavrayışını büyük ölçüde artırır
    • Yeni bir ortamda araçları öğrenmeye zaman ayırmak iyi bir yatırımdır
    • Araçları 2 hafta öğrenmek geliştirme hızını 2 katına çıkarabilir
    • Dokümantasyon yoksa diğer geliştiricilere sormak ve derine inmek gerekir
  • IDE kod tamamlama özelliği, tüm API’leri ezberlemeyi gereksiz kılar ve Java geliştirmede neredeyse vazgeçilmezdir
  • İyi bir debugger son derece önemlidir
    • Koşullu breakpoint’ler
    • İfade değerlendirme
    • Stack gezintisi
  • Yeni geliştiriciler, kullanabildikleri debugger’ı derinlemesine öğrenmelidir; bu, onlara bilgisayarlar hakkında üniversite derslerinden daha çok şey öğretebilir

Tip sistemi, ifadeler, DRY

  • Tip sisteminin en büyük değeri, nokta koyduğunuzda mümkün olan işlemlerin listelendiği araç desteğinde yatar
  • Tip doğruluğu güzeldir ama kod tamamlama ve gezinebilme daha büyük pratik değer sunar
  • Tip sistemini aşırı soyut biçimde kullanan geliştiricilere dikkat edilmelidir
    • Generics özellikle riskli olabilir
    • Çoğu durumda bunları container sınıflarıyla sınırlamak tercih edilir
  • Kısa koşul ifadelerini tek satıra yığmaktansa, anlamlı isimler verilmiş ara değişkenlere bölmek debugging ve anlama açısından daha iyidir
  • DRY iyi bir tavsiyedir ama denge gerekir
    • Basit ve açık tekrar eden kod, bazen karmaşık callback, closure veya nesne modeli yapılarından daha iyidir
    • Tekrarı azaltma çabasının kendisi karmaşıklığı artırıyorsa zarar verebilir

Concern separation, closure'lar, loglama

  • Separation of Concern güçlü bir fikirdir; ama pratikte davranışı anlamak için birçok dosya arasında gidip gelmeye zorlayarak zaman kaybettirebilir
  • Bunun yerine locality of behavior tercih edilir
    • Kodu “çalışan şeyin” yakınına koyarsanız, ona baktığınız anda ne yaptığını da görebilirsiniz
  • Closure'lar koleksiyon işlemlerini soyutlamak için uygundur, ama tuz gibi az miktarı yeterlidir
  • JavaScript’teki “callback hell”, closure'ların aşırı kullanımından doğan karmaşıklığın örneğidir
  • Loglama özellikle cloud deployment ortamlarında çok önemlidir
    • Ana mantık dallarının her birine log bırakılır
    • Birden çok makineden geçen isteklerde, logları gruplayabilmek için request ID eklenir
    • Mümkünse log level dinamik olarak ayarlanır
    • Mümkünse kullanıcı bazında log level ayarlanarak belirli kullanıcı sorunları debug edilir
  • Loglama kütüphaneleri karmaşık olabilir; ancak loglama altyapısını düzgün kurmaya yapılan yatırım sonradan büyük karşılık verir

Eşzamanlılık, optimizasyon, API

  • Eşzamanlılık korkulması gereken bir alandır; mümkün olduğunca basit modeller tercih edilir
    • Durumsuz web request handler'ları
    • Birbirine bağımlı olmayan uzak iş kuyrukları
    • Basit API'ler
  • Web’de optimistic concurrency iyi çalışabilir
  • Java’daki ConcurrentHashMap gibi eşzamanlılık veri yapıları bile dikkatle kullanılmalıdır
  • Optimizasyona, ancak gerçek performans profili somut bir sorunu gösterdikten sonra başlanmalıdır
    • Yalnızca CPU’ya bakmamak gerekir
    • Ağ erişimi çok sayıda CPU çevrimine eşdeğer olabilir; mümkün olduğunca azaltılmalıdır
    • İç içe döngü görüp hemen O(n^2) kaldırmaya girişmek karmaşıklığı artırabilir
  • İyi bir API, geliştiricinin fazla düşünmesini gerektirmemelidir
    • API’yi yazan kişi implementasyon bakışına ya da alan bakışına fazla kapılırsa kullanması zor hale gelebilir
    • Basit durumlar için basit API, karmaşık durumlar için ayrı daha karmaşık API sunan katmanlı yapı iyidir
    • Nesne yönelimli yaklaşımda davranış, mümkün olduğunca o nesnenin üzerinde olmalıdır
  • Java’nın stream/collector örnekleri, yaygın işleri gereksiz şekilde dolandıran API’ler olarak eleştirilir

Parsing, Visitor Pattern, frontend

  • Parser’ların recursive descent yaklaşımıyla yazılması eğlenceli ve zarif bulunur
  • Parser generator'lar, üretilen kodu anlama ve debug etme açısından zordur; ayrıca gramerin özyinelemeli doğasını gizler
  • Gerçek üretim parser’larının çoğu recursive descent kullanır; Bob Nystrom’un Crafting Interpreters kitabı önerilir
  • Visitor pattern kısaca “bad” diye özetlenir
  • Frontend ve backend’i ayırıp bunları HTTP üzerinden SPA kütüphanesi ve GraphQL JSON API ile bağlamak, karmaşıklık için iki ayrı yuva kurmaya benzer
  • Basit bir web sitesi ya da formu veritabanına yazmak gibi işlerde bile büyük frontend kütüphaneleri kullanma eğilimine karşı uyarılır
  • Karmaşıklığı düşürmek için htmx ve hyperscript oluşturulmuştur
    • Basit HTML korunur
    • Çok miktarda JavaScript’ten kaçınılır
  • React, iş bulma ve bazı uygulama türleri için daha iyi olabilir; ancak frontend karmaşıklığı yoluna giren bir tercih olarak görülür

Moda akımlar, FOLD, impostor syndrome

  • Geliştirme dünyasında çok sayıda moda akım vardır; özellikle frontend tarafında bu daha belirgindir
  • Devrimsel olduğu söylenen yeni yaklaşımlara şüpheyle yaklaşılmalıdır
    • Bilgisayar alanında birçok fikir zaten en az bir kez denenmiştir
    • Kötü fikirler yeni isimlerle geri dönebilir
  • Kıdemli geliştiricilerin açıkça “bu çok karmaşık, anlaması zor” demesi olumlu bir şeydir
  • FOLD, Fear Of Looking Dumb ifadesinin kısaltmasıdır; aptal görüneceği korkusuyla karmaşıklığı kabul edememe durumudur
    • Kıdemli biri “bu karmaşık” dediğinde, junior geliştiriciler de anlamadıklarını kabul etmeyi daha kolay bulur
    • FOLD, özellikle genç geliştiriciler arasında karmaşıklığın güç kazanmasının başlıca kaynaklarından biridir
  • Geliştiriciler, her şeyi kontrol ettiği hissiyle hiçbir şey bilmediği hissi arasında gidip gelir; impostor syndrome yaygındır
  • Herkes impostor gibi hissediyorsa aslında kimse impostor değildir; genç geliştiriciler hayal kırıklığı ve kaygı yaşasa da kariyerine devam edebilir

Önerilen okumalar ve sonuç

1 yorum

 
GN⁺ 2023-10-31
Hacker News görüşleri
  • Zeki insanların birer pervane gibi karmaşıklığa çekilmesi tuhaf
    Aşırı mühendislik yapma dürtüsüne karşı nasıl mücadele edileceğini öğrenmem yıllar aldı
    Bir kez fark etmeye başlayınca görmezden gelmek zorlaşıyor ve artık kodun aşırı mühendislik içerip içermediğini hemen anlayabiliyorum
    Ne yazık ki kodun yaklaşık %99’u aşırı mühendislik yapılmış gibi görünüyor ve geliştiricilerin kendi vazgeçilmezliklerini ve faturalandırılabilir saatlerini en üst düzeye çıkarma teşviki güçlü biçimde işliyor
    Tamamen mekanik ve egosuz görünen geliştiriciler bile sık sık aşırı mühendislik yapıyor; bu da bilinçsizce gerçekleşiyor
    Birçok geliştirici yazdığı her satırı bilinçli olarak düşünmüyor; sadece bir hedef koyup o hedefe biraz daha yaklaştıran ilk kodu çıkarıyor, bu yüzden her adımda daha iyi alternatifler olduğunu fark etmiyor

    • Geliştiricinin vazgeçilmezliğini ve faturalandırılabilir saatlerini artırma teşvikinin aşırı mühendisliğin nedeni olduğu durumlarla kendi deneyimimde neredeyse hiç karşılaşmadım
    • Bu meseleyle hâlâ boğuşuyorum
      Birincisi, eğlenceli bulmacaları seviyorum. Özellikle ticari kod, doğru yapıldığında çoğu zaman epey sıkıcı olabiliyor; bu yüzden bilinçsizce uygulanması eğlenceli olan özellikleri öne itiyorum. Buradaki eğlence, sonuçta her şeyi gereğinden fazla karmaşıklaştıran özellikler anlamına geliyor
      İkincisi, bir şeyi programlarken verdiğim her karar bana bariz ve gerekli görünüyor. Ancak daha sonra koddan uzaklaşıp ona taze gözlerle yeniden anlam vermeye çalıştığımda, işleri ne kadar berbat ettiğimi görebiliyorum
      Çoğu problemde en göze çarpan çözüm çoğu zaman epey karmaşık oluyor; basit çözümün nerede bulunacağını bilmek için bilgelik, beceri ve alan bilgisi gerekiyor. Basit ve temiz çözümler neredeyse hiç apaçık olmuyor
      “Yavaş yavaş yarım yamalak bir mesaj kuyruğu uyguluyoruz. Gidip standart bir mesaj kuyruğu kullanalım”, “Hatalarla dolu özel bir ikili çerçeveleme protokolü yapıyoruz. Gidip protobuf/msgpack kullanalım”, “Veri almak için özel bir RPC protokolü oluşturmayalım, HTTP üzerinde REST kullanalım. Böylece araya nginx koyup backend yanıtlarını önbelleğe alabilir ve özel önbelleği de atabiliriz”
    • Bana bir yazarın mektubundaki şu tür ifade hatırlatıyor: “Kısa yazacak vaktim olmadığı için uzun bir mektup oldu”
      Sonuçta zamanınız varsa ve bunun için ödüllendiriliyorsanız kusursuz, basit ve tekrarsız kod yazabilirsiniz. Ama çoğu durumda ödüllendirilen şey, bir şeyi yayına almak ve onu yayına çıkarmak için harcanan iş miktarı, zeka ve tasarım becerisiyle teknik yetkinlik göstermektir
      Doğal sonuç, her şeyin şişmiş ve aşırı mühendislik içeren geçici çözümler yığınına dönüşmesi ve her 3-7 yılda bir yeniden yazılması oluyor
      Veriye bakmadım ama “yeniden yazım yarı ömrü”nün işten ayrılma oranı ya da ortalama görev süresiyle ilişkili olduğunu tahmin ediyorum. İnsanlar aşırı mühendislik yapmamaya daha çok uğraşsa bile, zaten eninde sonunda tekrar yazılması muhtemel
      Bir mükemmeliyetçi olarak bu gerçekten sinir bozucu, ama en iyi basit çözüm üzerine daha uzun düşünmektense karmaşık ve aşırı mühendislik yapılmış bir şey üretmenin daha çok ödüllendirildiği durumlar var. Daha iyi organizasyonlar vardır elbette ama 9 yıldır yazılım mühendisi olarak çalışıyorum ve henüz bulamadım
      Aklıma gelen en iyi karşı örnek açık kaynak projeleri, ancak iyi kütüphaneler bile bakımcı değişince yeniden yazılıyor ya da yeni sürümleri çıkıyor. Açık kaynak ile HN’deki birçok tam zamanlı yazılım mühendisinin gördüğü kurumsal ıvır zıvır arasında maddi teşvikler çok farklı. Bu, iyi cilalanmış akademik bir makaleyle alelacele yazılmış iş e-postasını karşılaştırmaya benziyor
    • Benim durumumda aşırı mühendislik genelde ters yönden geliyor. Kod yazarken fazla düşünmekten ve kod tabanının nasıl görünmesi gerektiğine dair önyargılara sahip olmaktan kaynaklanıyor
      Handmade Hero’daki Casey’nin kendi programlama tarzını “compression-based” diye adlandırdığını hatırlıyorum. Önce kodu yazıp sonra birlikte ait olan şeyleri kademeli olarak ayırma yaklaşımı
      Tekrar oluştuğunda soyutluyorum; bilinçli tasarımla soyutlamıyorum. Giderek bu yöntemi daha fazla kullanıyorum
    • Eğer “kodun %99’u aşırı mühendislik yapılmış gibi görünüyor” sonucunuz size sürekli %99’luk cevaplar veriyorsa, o zaman şimdiye kadar öğrendikleriniz geçerli olsa bile kurduğunuz düşünce modelinde bir sorun olabileceğini düşünmez misiniz?
      Bu, tek başına mutlaka yanlış olduğu anlamına gelmez ama başkalarının iş kalitesini değerlendirmek söz konusuysa güçlü bir önyargı karışmış olma ihtimali yüksek görünüyor
  • Bu siteyi gerçekten seviyorum ve beni hep güldürüyor. Özellikle en sevdiğim kısmı mikroservisler
    “grug, büyük beynin en zor problem olan sistemi doğru şekilde bölme işini alıp neden buna bir de ağ çağrıları eklediğini merak ediyor. grug’a çok kafa karıştırıcı görünüyor”

    • Bu siteyi seviyorum ve sık sık okuyorum. Tanıdığım insanlar artık grug brain adlı yazılım geliştirme manifestosundan bıkmış olabilir
      “Karmaşıklık çok, çok kötüdür”
      “Karmaşıklık ile Tyrannosaurus’la bire bir düello arasında seçim yapması gerekse grug Tyrannosaurus’u seçer. En azından grug Tyrannosaurus’u görebilir”
  • Türler konusunda bazı şikayetlerim var
    grug, tip sistemlerinin değerinin %90'dan fazlasının klavyede noktaya bastığında yapılabileceklerin listesinin sihirli şekilde çıkmasında olduğunu söylüyor ama bizim şirkette junior'lar production'a null erişimi yüzünden bozulan kodları sık sık deploy ediyor ve bunu bize Sentry söylüyor
    Yoğun geliştirme dönemlerinde, junior geliştirici başına günde tespit edilen yaklaşık bir null erişim bug'ı çıkıyor
    Statik kontrolü olan düzgün bir tip sistemi kullansak IDE'de “bu null olabilir, emin misin?” diye uyarır ve bu inanılmaz faydalı olurdu
    Ayrıca statik tipler olmasa da otomatik tamamlama mümkündür
    “Büyük beyinli tip sistemi şamanları tip doğruluğunun tip sisteminin özü olduğunu söyler ama grug, o şamanların sık sık kod deploy etmediğini görür. Deploy edilmeyen kod bir bakıma doğru olabilir ama grug'ın bahsettiği doğruluk o değil” kısmı kaba ve gereksiz
    Başlıca C, PHP, Python, Haskell ve tip eklenmiş Python ile kod deploy ettim; tipli dillerde production'a kadar ulaşan bug oranı çok daha düşük. Türleri sevmemin sebeplerinden biri de bu
    Ayrıca refactoring çok daha kolay oluyor. Yaygın kullanılan bir şeyi değiştirdiğinde, tüm kod tabanında bozulan çağrı noktalarını saniyeler içinde güvenilir şekilde görebiliyorsun ve bu, büyüyen kod tabanını tekrar tekrar iyileştirmede çok yardımcı oluyor

    • O kadar da yanlış mı? Kendi söylediklerine bakınca, biçimsel kanıtı zorlayan tip sistemlerine kadar gitmeyi kabul etmiyor gibi görünüyor
      Bunun yerine bazı sorunları yakalayan ve her şeyden önce otomatik tamamlama sihri sunan ama tam doğruluk kanıtı için gereken tüm ayrıntılara takılmayan uzlaşmacı tip sistemlerini kabul ediyor gibi
    • Sadece şaka. Muhtemelen alay edilen tarafta yer alma ihtimalim daha yüksek ama bunu fazla kişisel almaya gerek olmadığını düşünüyorum
      C ya da Java seviyesindeki statik tiplerin iyi ya da kabul edilebilir olduğunu, Rust veya Scala'da görülen daha gösterişli şeylerin ise zaman kaybı olduğunu düşünüyor gibi. Ben tamamen haksız olduğunu düşünüyorum ama hayat böyle
    • Asıl metin tipli dillere destek veren bir yazı değil mi? Sonuçta aynı noktada buluşuyor gibi, o yüzden kafam karıştı
    • Buradaki “şamanlar”ın sizin gibi insanları kastettiğini sanmıyorum
      “Büyük beyinli tip sistemi şamanları”nı, mutlaka kod yazan kişiler değil de örneğin bu konuda eğitim satıp insanları gaza getiren kişiler olarak anladım
      Yazının başlarında Agile'dan bahsederken de “şaman” ifadesini kullanıyor; gerçek yazılım geliştirmeden çok eğitim satmaya yakın işler yapan epey kişi var
    • Daha önce “büyük beyinli tip sistemi şamanları” ile çalıştım. Hatta bu yazı bana çok nazik ve cömert bir analiz gibi geliyor
      Tip hiyerarşisine takıntılı insanlarla çalışmak katlanılmaz ve gerekçelendirme genelde “ya şöyle olursa” ve “ama bu sound değil” dünyasında kalıyor
      Tip sisteminin yol açtığı kalite düşüşünün büyük kısmı, yeterince tip eklersen bug'ları tamamen önleyebileceğine inanan insanlardan geliyor, ama bu doğru değil
  • Önümüzdeki birkaç ay içinde herkesin HTMX trenine bineceğini ve bunun birçok genç geliştiricinin kafasını sarsarak dünya çapında büyük ölçüde enerji tasarrufu sağlayıp pek çok insanı mutlu edeceğini düşünüyorum
    Sonra bu meraklı gençler htmx.org'daki linklere tıklamaya devam edip hyperscript'i keşfettiğinde, Dusk till Dawn'da vampirlerin ortaya çıktığı an gibi olacak

    • Herkesin HTMX trenine binmesi, JavaScript dünyasında sonsuz döngü demek
      JavaScript karmaşıklığından bıkan biri basit bir JavaScript kütüphanesi yapar, insanlar o sadeliğe üşüşür, sonra tüm web özelliklerini desteklemek zorunda kaldığı için o kütüphane karmaşıklaşır ve ardından yine o karmaşıklıktan bıkan biri gidip basit bir JavaScript kütüphanesi yapar
      Saf JavaScript ile başladım, yıllarca IE5/6 ile boğuştum, sonra jQuery herkesi kurtardı; AngularJS pek bana göre değildi, o yüzden pas geçtim; React beta çıkınca fonksiyonel programlama idealleri yüzünden hoşuma gitti. Şimdi ise transpiling, hot reload, Typescript ve ağır React kütüphane yığınlarının içinden geçiyorum
      Intercooler ve HTMX ile de birkaç proje yaptım. HTMX genel olarak sağlam ama bu kasabadan ilk geçen tren değil
    • Aa, Carson Gross hem grug brained developer'ın hem de htmx'in yazarıymış
      htmx hakkında gerçek eleştiriler görmek isterim
      Bana göre web'in büyük ve kalıcı meselelerinden biri sayfaları iyi şekilde güncellemenin yolunu bulmak oldu ve bunun için sürekli her türlü şeyi denedik. Bu da yorgunluk yaratıyor; bazı fikirler aşırıya kaçıyor ya da zamanla dağınık bir şeye dönüşüyor
      Htmx, grug tarzı bir tepki gibi görünüyor: daha az şey, YAGNI'ye ısrarla bağlılık
      Gelecek belirsiz ama signals gibi işler hâlâ kutsal bir uğraş gibi görünüyor. Birçok yönden çok sayıda deneme yapılıyor ve bu cephede de başka cephelerde de hâlâ keşif halindeyiz
      MobX ve Svelte gibi şeyler de zaten uzun bir yol kat etti. Yolculuk henüz bitmedi ve karmaşıklık canavarıyla sürekli boğuşuyor olmamızın, muhafazakâr ya da grug tarzı düşünce bunu öyle görebilse bile, zayıflık işareti değil; sadece basit olanı değil, basit ve iyi olanı bulmaya yönelik haklı bir çaba olduğunu düşünmek istiyorum
    • O cümleyi görünce güldüm, sonra gerçekten kontrol ettim
      _="on load wait 5s then transition opacity to 0 then remove me"
      Ah, hayır
      _="on htmx:error(errorInfo) fetch /errors {method:'POST', body:{errorInfo:errorInfo} as JSON} "
      Ah, hayır!
  • 30 yıldır geliştirici olarak çalışıyorum ve ilk zamanlar kibirli olduğumu, kendimi başkalarından daha zeki sandığımı kabul ediyorum. O zamanki ben, bütün karmaşıklık şeytanlarını seven “büyük beyin” tarafındaydı
    10 yıl sonra daha çok “Grug brain” geliştiriciye dönüştüm ve şimdi kusursuz olmayabileceğini bilsem de işe yarayan en basit çözüme odaklanıyorum. Bunun yine de iyi olmasının nedeni, beni doğru olana daha çok yaklaştırması ve yinelemeli iyileştirmeyi mümkün kılması
    Bir geliştiricinin yapabileceği en iyi şey kod silmektir. Şu anda iki yıldır sürdürdüğümüz bir gereksinim aniden artık gereksinim olmaktan çıktı ve bir sürü kodu söküp atacak olmaktan gerçekten heyecan duyuyorum. Çünkü her şey daha basit hale geliyor

    • Kodu sildiğinde, başının arkasında tarif etmesi zor hoş bir his oluyor
      Sanki açılan alanı bedenen hissediyorsun gibi
  • Grug, bir hafta önceki Philosophy of Software Design yazısının yorumlarında da geçmişti; o zaman da tartışmanın epey iyi olduğunu düşünmüştüm. https://news.ycombinator.com/item?id=38011938
    “Grug hakkında ben de tam olarak aynı hissediyorum. İnsanların neyin basit olduğu konusunda gerçekten uzlaştığını sanmıyorum; bu yüzden kendi ‘basitlik’ anlayışını sanki bir mağara adamının bile kabul edeceği apaçık bir şeymiş gibi sunmak bana gösteriş gibi geliyor.”
    Basitlik çoğu zaman keşfedilmesi en karmaşık şeylerden biri oluyor. Etrafındaki her şeyin, ama kendi yaptığı iş hariç, karmaşık olduğuna ve bu yüzden basitliğe zorlanması gerektiğine kesinlikle inanan birçok insan gördüm. Bu, otoriteye tutunan tehlikeli derecede zayıf bir tavır gibi geliyor

    • İyi bir nokta. Ama bence asıl mesele, sonuçta kötü felsefenin karmaşıklığı teşvik etmesi
      grug brain felsefesi, kesinlikle kaçınılmaz olduğu durumlar dışında, bedeli ne olursa olsun basitliği seçmektir
      grug’ın gözündeki büyük beyin felsefesi ise, kesinlikle kaçınılmaz olduğu durumlar dışında, bedeli ne olursa olsun yeniden kullanılabilirliği seçmektir
      Bu felsefenin sorunu, birinci nesil tasarım tercihlerini kalıcı hale getirmesi ve yinelemeli iyileştirmeyi zorlaştırmasıdır
      Basitliği bulmanın zor olduğu doğru, ama basitliği bulmanın anahtarı yinelemeli iyileştirmedir
    • Grug yazısında özellikle iyi olan şey, nüans ve alçakgönüllülükle dolu olması. Gösteriş değil
    • Bence kod satırı sayısını ölçmek yeterli
      Yerel minimum, inşa ettiğiniz şeyin karmaşıklığına göre değişir; bu yüzden oldukça akıllı birkaç farklı görüşün aynı anda doğru olmasına yer vardır
      Mükemmel bir ölçüt değil ama yönü doğru gösteriyor ve logaritmik ölçekte çok iyi çalışıyor
  • Chesterton’ın Çiti kavramını sayısız kez kullandım ve açıkladım; adını öğrenmiş olmak güzel
    Yeni geliştiricilerle çalışırken bu gerçekten çok sık oluyor. “Eski legacy çöpü”nü gördüklerinde ilk tepkileri onu söküp atmak ya da her şeyi çöpe atıp sıfırdan yeniden yapmak oluyor
    Bazı durumlarda bunu bizzat denemelerine izin vermek de öğretici olabilir, ama bizden önce gelen insanların hepsinin tamamen aptal olmadığını ve çoğu zaman bunu bir sebeple yaptıklarını hatırlamak iyi olur
    Bazen gerçekten değiştirilmesi gereken dağınık eski koddur; ama o durumda bile, o alanda bir şey inşa edebilmek için anlaşılması ve ele alınması gereken tüm köşelerle edge case’lerin zorlukla kazanılmış bir kaydını barındırıyor olabilir

  • Testlerle ilgili kısım gerçekten çok iyi. Birkaç yıldır öğrendiklerimle tam olarak örtüşüyor
    Hata bulmak için doğru nokta entegrasyon testleri
    Mock nesneler işleri gereğinden fazla karmaşıklaştırma eğiliminde ve hâlâ ara sıra kullanıyorum ama sistematik olarak kullanmaktan kaçınıyorum
    Birim testleri refactoring karşısında fazla kırılgan olurken, entegrasyon testleri refactoring’e yardımcı oluyor

    • Sevdiğim küçük bir hile, demo senaryosunu izleyen entegrasyon testleri yazıp demodan hemen önce çalıştırmak. Mümkünse iki kez çalıştırıyorum
    • Buna güçlü biçimde katılmıyorum. Entegrasyon testleri, belli bir ölçek ya da karmaşıklığa ulaşılana kadar harika çalışır ama o çizgi aşıldığında gerçekten kötüleşir
      Birim testleri yazması ve bakımını yapmak daha zordur, ama başarısız olduklarında anlamak ve debug etmek çok daha kolaydır; bu yüzden uzun vadede çok daha iyi dayanırlar
      En kötü testler, başka entegrasyon testlerinin daha önce çalıştırılmış olmasına gizlice bağımlı olan entegrasyon testleridir. %99 oranında doğru çalışırlar ama bir değişiklik yüzünden sıra değiştiği anda bozulurlar
    • Testler hakkında vardığım sonuç şu
      Ekipte basit kod varsa testler çok yardımcı olur. Ama ekipte basit kod yoksa, ki genelde yoktur, test yazmaya harcanacak zamandan ziyade kodu basitleştirmeye zaman harcamak daha iyidir
    • Bence bunun büyük kısmı neyi “birim” saydığınıza bağlı
      Tek bir leaf function’ı birim almak çoğu zaman fazla düşük seviyede kalır, ama görece istikrarlı arayüzlere sahip daha büyük modüller test edilmesi verimli, iyi bir birim olabilir
  • “Karmaşıklık çok çok kötüdür”
    “Karmaşıklık-ruh şeytanına karşı en iyi silah büyülü kelime ‘hayır’dır”
    “Üzücü ama gerçek: ‘evet’ demeyi öğrendikten sonra başarısız olursan, başka bir grug’ı suçlamayı öğrenmek ideal kariyer tavsiyesidir”
    Bu, grug’ın karmaşık bilgeliği

  • Bu o zaman da tartışılmıştı
    The Grug Brained Developer - https://news.ycombinator.com/item?id=31840331 - Haziran 2022, 374 yorum

    • Karmaşıklık hâlâ çok kötü