5 puan yazan GN⁺ 5 일 전 | 1 yorum | WhatsApp'ta paylaş
  • Projeler kolayca iki akıştan birine ayrılır: hemen yapıp bitirme akışı ve araştırma ile tasarım büyürken asıl problemi gözden kaçıran akış; gerçek ilerlemede ise çoğu zaman oturup denemek daha öne geçer
  • Emacs için fuzzy path araması yaparken bile iyi bir kütüphanenin ek özellikleri yeni gereksinimler doğurarak tasarımı şişirdi; sonunda ihtiyaç olmayan anchor özelliği kodunun tamamını atıp YAGNI ilkesini yeniden doğrulamış oldu
  • Kod diff’lerinde satır bazlı karşılaştırma, fonksiyon veya type gibi üst düzey yapıları düzgün yakalayamaz; treesitter tabanlı araçlarda da entity eşlemesi kayarsa silme ve eklemeleri uzun uzun gösterip okunabilirliği bozabilir
  • Gerekli yön, önce LLM çıktısının tur bazlı gözden geçirilmesine uygun minimum kapsamlı araçlar yapmak; Rust için entity çıkarma ve basit eşleme ile başlayıp üst düzey değişiklik özetini hızla görmeye yarayan iş akışı öncelikli

Aşırı düşünme ve kapsam genişlemesi

  • Projeler kolayca iki yola ayrılır: hemen yapıp bitirme akışı ve önceki örnekleri deşerken kapsamın büyüyüp sonunda asıl problemi çözemeyen akış
  • Hafta sonunda yapılan mutfak rafında, kahve içerken tasarım kararlaştırıldı, 3D baskı askı birkaç kez revize edildi ve elde kalan malzeme ile boya kullanılarak hafta bitmeden tamamlandı
    • Ikea bin askısı için CAD, OnShape CAD olarak açık durumda
    • Malzemeler atölye alanından arta kalanlardan yeniden kullanıldı; köşeler de palm sander ile göz kararı yumuşatıldı
  • Bu rafta asıl başarı ölçütü, mutfağa tam uyan bir eşya üretmekten çok bir arkadaşıyla birlikte ahşap işi yapmanın keyfiydi; bu da ayrıntılı ölçütleri gereğinden fazla düşünme ihtiyacını azalttı
  • Buna karşılık yapısal diff ararken difftastic sonuçları yetersiz gelince ilgili araçlar ve iş akışları 4 saat boyunca araştırıldı; sonunda yeniden Emacs’te kullanılacak daha iyi bir diff iş akışı şeklindeki asıl ölçüte geri dönüldü
  • Donanım prototipleme arayüzleri, Clojure ve Rust’ı karıştıran bir dil, CAD için bir dil gibi uzun süredir ilgi duyulan konulara arka plan araştırması ve küçük prototiplerde yüzlerce saat harcandı; ancak bunlar hâlâ ilk motivasyonu doğrudan çözen bir ürüne dönüşmedi
  • Dil ve CAD projelerinde, Rust veya Clojure’un yerine geçip geçmeyeceği, sadece bazı sorunları mı ele alacağı, öğrenme amaçlı bir oyun alanının yeterli olup olmayacağı, ticari CAD’i değiştirip değiştirmeyeceği ya da başkaları için de faydalı olması gerekip gerekmediği gibi başarı ölçütleri belirsiz
  • Bu soruları değerlendirmek değerli olsa da, çok şeyi yalnızca değerlendirmektense gerçekten çok şey üretmenin daha iyi olduğu düşünülüyor
  • Geriye dönüp bakınca açıkça iyi olmayan çıktılar çıksa bile, genel toplamda oturup denemek daha ileride götürüyor

Kapsam genişlemesinin korunumu yasası

  • Düşünmeden üretmenin de bir sınırı var ve denge gerekiyor; LLM agent ile çok fazla kod yazdırıp sonunda hepsini çöpe atma deneyimi, YAGNI ilkesini yeniden hatırlattı
  • Emacs’te kullanılacak Finda tarzı, tüm dosya sisteminde fuzzy path araması yapmak isteniyordu; aynı işlev daha önce elle kodlandığı için LLM gözetilirse birkaç saatte biteceği düşünülüyordu
  • Başta planlama konuşmasında Nucleo önerildi; iyi tasarlanmış ve belgelenmiş görünüyordu, bu yüzden smart case ve Unicode normalization özelliklerinden yararlanmak için benimsendi
    • Örneğin foo sorgusu hem Foo hem foo ile eşleşirken, Foo sorgusu foo ile eşleşmiyor
    • cafe ile café işleme mantığı da aynı bağlamda ele alınıyor
  • Sorun iyi bir kütüphanenin kendisi değildi; Nucleo’nun ayrıca anchor özelliğini de desteklemesiydi
  • Yalnızca dosya yollarından oluşan bir corpus’ta satır başı anchor anlamlı görünmediği için, bu özelliği path segment tabanlı anchor olarak yorumlama fikri ortaya çıktı
    • Örneğin ^foo, /root/foobar/ ile eşleşmeli ama /root/barfoo/ ile eşleşmemeli diye düşünüldü
  • Bunu verimli yapmak için indeksin segment sınırlarını saklaması ve her segment için sorguyu hızlıca test edebilmesi gerekiyordu
  • Buna bir de ^foo/bar gibi slash içeren anchor sorgularını ele alma gereği eklendi; yalnızca segment bazlı kontrol, /root/foo/bar/baz/ gibi yolları doğru eşleştirmeyi zorlaştırdı
  • Bu tasarım için birkaç saat daha harcandı; LLM ile fikir alışverişi yapıldı, Nucleo type’larını saran kod yazıldı, sonra kodun aşırı şiştiği ve tatmin etmediği görülünce daha küçük bir wrapper baştan elde yazıldı
  • Ara verildikten sonra, Finda’da anchor özelliğine gerçekten ne zaman ihtiyaç duyulduğu hatırlanamadı; ayrıca path corpus’ta sorgunun başına veya sonuna / eklemenin çoğu anchor işlevini zaten karşılayabildiği fark edildi
    • Tek istisna dosya adı sonunu hedefleyen anchor olarak kaldı
  • Sonunda anchor ile ilgili tüm kod atıldı; LLM ve başkalarıyla yapılan tartışmalar olmasa baştan doğrudan yazmaya kıyasla yine de kazançlı olup olmadığı ise belirsiz kaldı
  • Programlama hızı arttıkça beraberinde gereksiz özelliklerin, rabbit hole’ların ve dolambaçlı yolların da arttığı bir korunumu yasası varmış gibi görünüyor

Yapısal diffing

  • Kodda diff genelde bir dosyanın iki sürümü arasındaki satır bazlı değişiklik özeti anlamına gelir; unified view’da ekleme ve silmeler +, - ile gösterilir
  • Aynı diff yan yana karşılaştırma biçiminde de render edilebilir; değişiklik karmaşıklaştıkça bu sunum daha okunaklı olabilir
  • Satır bazlı diff’in sorunu, fonksiyon veya type gibi üst düzey yapıları tanımamasıdır; süslü parantezler bir şekilde denk gelse bile, aslında farklı fonksiyonlara ait yerlerde gösterimin atlandığı durumlar olabilir
  • difftastic, treesitter tarafından sağlanan concrete syntax tree’yi kullanarak bu sorunu azaltmaya çalışır; ancak sürümler arasındaki entity eşlemesi her zaman doğru çalışmaz
  • Doğrudan tetikleyici olan diff’te struct PendingClick, iki tarafta birbirine karşılık gelmedi ve solda silinmiş, sağda eklenmiş gibi gösterildi
  • Eşlemenin neden başarısız olduğuna derinlemesine bakılmadı; ancak toplam diff uzasa bile PendingClickRequest ile PendingClick yapılarını iki tarafta da karşılıklı görmek daha iyi bulundu

Yapısal diff araçları ve referanslar

  • En olgun ve dikkatle parlatılmış semantic diff aracı olarak semanticdiff.com öne çıkarılıyor
    • Almanya’daki küçük bir şirket tarafından sunuluyor; ücretsiz bir VSCode eklentisi ve GitHub PR diff’lerini gösteren bir web uygulaması bulunuyor
    • Ancak istenen iş akışının temeli yapılabilecek bir kod kütüphanesi sunmuyor
    • semanticdiff vs. difftastic yazısında yararlı birçok ayrıntı var; buna difftastic’in Python’da anlamlı indentation değişikliklerini bile gösterememesi de dahil
    • Yazarlardan biri HN yorumunda, anlambilim işlemek için treesitter kullanma yaklaşımından uzaklaştıklarını; bağlama bağlı anahtar kelimeler ve lexer davranışı nedeniyle parse işleminin bozulabildiğini, bu yüzden async gibi bir adı parametre olarak kullanmanın bile aracı kilitleyebildiğini söylüyor
  • diffsitter treesitter tabanlı ve bir MCP server içeriyor
    • GitHub yıldız sayısı yüksek olsa da belgeleri çok iyi görünmüyordu; nasıl çalıştığını anlatan materyal bulmak zordu
    • difftastic wiki’sinde, ağacın leaf düğümleri üzerinde longest-common-subsequence çalıştırdığı yazıyor
  • gumtree, 2014 tarihli araştırma/akademik kökenli bir araç
    • Java gerektirdiği için Emacs içinde hızlıca kullanılacak kişisel bir araç olma amacına uymuyor
  • mergiraf, Rust ile yazılmış, treesitter tabanlı bir merge-driver
    • architecture overview iyi düzenlenmiş ve içeride Gumtree algoritmasını kullanıyor
    • Belgeleri ve diyagramları, dikkatle hazırlanmış bir proje izlenimi veriyor
    • semanticdiff.com yazarı HN yorumunda, GumTree’nin sonucu hızlı verdiğini ancak çeşitli takip makalelerindeki iyileştirmelere rağmen sık sık kötü eşleşmeler döndürdüğünü; sonunda eşleme maliyetini minimize eden dijkstra tabanlı bir yaklaşıma geçtiklerini belirtiyor
  • weave, Rust ile yazılmış bir başka treesitter tabanlı merge-driver
    • Gösterişli açılış sayfası, yüksek GitHub yıldız sayısı ve MCP server gibi unsurlar genel olarak biraz abartılı bir izlenim veriyor
    • Entity çıkarma crate’i olan sem incelendi
    • Çekirdek diff kodu fena değil ama biraz lafı uzatıyor; entity eşlemesi için ise greedy algoritma kullanılıyor
    • Veri modeli, dosya içi taşınmaları algılayamıyor; oysa bu tür taşınmalar anlamlı olabilir
    • Güvenilir sayılabilmesi için daha güçlü dil entegrasyonu gerektiriyor gibi duran, sezgisel kurallara dayalı çok sayıda impact analizi de içeriyor
      • sem diff --verbose HEAD~4 çalıştırıldığında, gerçekte değişmemiş satırların değişmiş gibi işaretlendiği hatalı çıktı da görüldü
    • %80 tamamlanmış gibi duran varsayımsal faydalı özelliğin çokluğu yüzünden temel alınacak bir yapı gibi görünmese de, 3 ayda bu seviyeye gelmiş olması takdir ediliyor
  • diffast, 2008 tarihli akademik bir makaledeki algoritmaya dayanarak AST üzerinde tree edit-distance hesaplıyor
    • Python, Java, Verilog, Fortran ve C/C++ için özel parser’larla destek sunuyor
    • example AST differences gallery oldukça iyi düzenlenmiş
    • Bilgiyi tuple biçiminde dışa aktararak datalog ile kullanıma uygun hale getiriyor
  • autochrome, Clojure’a özel bir diff aracı ve dynamic programming kullanıyor
    • Görsel anlatımı ve örnekli walkthrough’su çok başarılı
  • Tristan Hume’un Designing a Tree Diff Algorithm Using Dynamic Programming and A* yazısı, tree diff algoritması tasarımı açısından değerli bir referans

İstenen iş akışı ve minimum kapsam planı

  • Ana kullanım senaryosu LLM çıktısının tur bazlı incelenmesi; agent’ın tek seferde 10 bin satırdan fazla kodu kontrolsüzce üretmesine izin verilmiyor
  • Agent’a kapsamı belirli işler veriliyor, birkaç dakika sonra geri dönülüp genel değişiklik özeti görülüyor; ardından Emacs içinde doğrudan düzeltme yapma, hepsini atıp yeniden deneme ya da baştan elde yazma tercih edilebiliyor
  • İstenen iş akışı, hangi type, function ve method’ların eklenip silindiğini ya da değiştiğini önce üst düzey bir özetle görmek
  • Bunun üstünde her entity için metin diff’ini hızla açabilmek ve özetten ayrıntı diff’ine doğal biçimde inebilmek gerekiyor
  • Ayrıca değişiklikleri başka bir görünüme geçmeden doğrudan düzenleyebilmek, yani diff ekranından file ekranına geçmeden inline düzenleme yapılabilmesi isteniyor
  • Hedef, Magit’in değişiklik inceleme ve staging iş akışını dosya/satır düzeyinden entity düzeyine taşımak
  • Bu kez yeniden hatırlanan minimum kapsam dersine uygun olarak, önce yalnızca Rust için treesitter tabanlı bir entity çıkarma çerçevesi hızla elde yazılacak
  • Eşleme önce basit bir greedy yöntemle başlayacak; diff ise komut satırında render edilecek
  • Bu kadarı bile belirli bir commit’te difftastic’ten daha iyi sonuç verirse, sonrasında bunu Magit benzeri daha etkileşimli bir Emacs iş akışına bağlama düşünülüyor
    • Mümkünse Magit’in kendisini yeniden kullanma ihtimali de açık tutuluyor
    • Yeni dil desteği yalnızca ihtiyaç oldukça eklenecek
    • Sonrasında basit greedy yerine puan tabanlı küresel eşleme de araştırılabilir
  • Yeterince tatmin edici olursa yayımlanabilir; ama GitHub yıldızı ya da HN karma toplamak hedef değil, araç sessizce tek başına kullanılmak üzere de kalabilir
  • Bazen insanın sadece bir raf istediğini söyleyerek metin, aşırı genişleme yerine yalnızca gerekli olanı yapma tutumunu yeniden bağlıyor

1 yorum

 
GN⁺ 5 일 전
Hacker News görüşleri
  • Bence bu, PhD araştırmasının en büyük zorluklarından birini çok iyi gösteriyor
    İlginç bir konu seçip ilgili önceki çalışmaları olabildiğince çok okudukça, yapmayı düşündüğün şeyin aslında ne kadar çoktan yapılmış olduğunu fark ediyorsun ve scope creep ciddi şekilde artabiliyor
    Başlangıçtaki enerji ve heyecanı tükettikten sonra, kalan %20-30'u zorlayarak yayına uygun bir duruma getirmek zorunda kalıyorsun

      1. günde, mevcut endüstriyel katalizörleri yeni bir kullanım alanına uyarlayıp temel ilaç öncüllerinin üretim maliyetini düşürmeye çalışarak başlıyorsun
      2. günde ise neredeyse her şeyin teorisini açıklamış, bilinen evrendeki tüm kuvvetlere aracılık eden evrensel parçacığı tespit etmek için bir Lagrange noktası yörünge deney düzeneği kurmaya kalkışıyorsun
    • Bu his bana fazlasıyla gerçek geliyor
      Bunu hafifletmek için ne yapmak gerektiğini merak ediyorum
    • Doktora sürecinin çoğunda bunun yaşanmasının sebebi, PhD'nin nihai amacının normal science yapabildiğini kanıtlamak olması diye düşünüyorum
      Pratikte yapılan şey, sistemin gözlemlenebilirliğini %1'den %1.001'e çıkarmak gibi bir iş ve akademik kariyere giriş için bir eşik olmaya daha yakın
      Bu yüzden gerçekten ilginç, son derece yeni ya da bilime doğrudan uygulanabilir içerik taşıyan tezlere neredeyse hiç rastlamıyorum
    • Üstelik buna, en başta PhD'ye başlamış olmaktan duyulan pişmanlık da giderek ağırlaşırken katlanmak zorundasın
    • Mümkün olduğunca tüm önceki çalışmaları okuyup öyle başlamak kesinlikle yanlış bir yaklaşım gibi geliyor
      Gerçekte böyle araştırma yapan neredeyse kimseyi görmedim; genelde iki üç makale okuyup oradan inşa etmeye başlamak daha doğru
      Literatürü derinlemesine taramak için en iyi zamanın, biraz sonuç çıktıktan ve yazıya dökmeye başladıktan sonrası olduğunu düşünüyorum
  • Aklıma sürekli daha iyi olanın yeterli olduğu fikri geliyor
    Küçük iyileştirmeler zamanla birikir ve en baştan kusursuz, tamamen yeni bir şey yoktur; bu yüzden oturup mükemmel tasarımı çıkarmaya çalışmak çoğu zaman ters teper
    Engelin yolun kendisi olması sözü de buraya çok uyuyor

    • Mükemmelliğin yeterince iyinin düşmanı olmasına izin verme sözü tam yerinde
      Birlikte çalıştığım bir ekip arkadaşı, kod değişikliklerini eleştirirken bile fazla önemsiz bir noktaya takıldığını hissederse "eskisinden daha iyi" derdi
      Bu sayede hem geliştirilecek noktaları işaret eder hem de küçük kusurlar kalsa bile ilerlemenin sorun olmadığını hissettirirdi; bu tavrı güçlü biçimde destekliyorum
    • Bu sonuçta mükemmeliyetçilik
      Eskiden mükemmeliyetçiliği yalnızca aşırı yüksek başarıyı zorlayarak kovalamak sanırdım, ama kusursuz değilse kabul edemeyip ilerlemeden vazgeçmek de mükemmeliyetçilik olabilir
      Büyük işleri ertelemek anlamındaki procrastination da çoğu zaman aynı kökten geliyor
  • Rec Room CEO'sunun söylediği bir şey hoşuma gitmişti
    Ekipler her zaman projeyi daha kısa sürede bitirmiş olmayı ister; çıkışı daha da geciktirip daha karmaşık hale getirip daha fazla parlatmış olmayı isteyenlere ise neredeyse hiç rastlanmaz
    Her duruma %100 uymaz belki ama hata yapacaksan, gereğinden fazla büyütüp zaman kaybetmek yerine küçük yapıp erken yayınlamak daha iyi gibi geliyor

  • İnsanlar doğaları gereği benzer fikirler üretmeye yatkın; bu yüzden habersizce bir projeyi tamamlarsan sonuç bir ölçüde yeniden icat etmeye çıkabiliyor
    Tersine, önceden araştırırsan bunun kısmen zaten var olan şeylerin tekrarı olduğunu fark edip hevesin kaçabiliyor
    Yine de kendi öğrenimin için sonuna kadar inşa etmenin kendisi en önemli şey olabilir
    Elbette yeni akademik çıktı üretmen ya da benzersiz bir projeden gelir elde etmen gerekiyorsa bu daha zor, ama o alanlar bile mevcut bir şeyi azıcık eğip bükmeye şaşırtıcı ölçüde toleranslı

  • Şu anda bir yan projede tam olarak bunu yaşıyorum
    Alanım Information Retrieval ve deneyimim az olduğu için öğrenebileceğim ya da entegre edebileceğim çok fazla prior art olması doğal
    Bu yüzden bu yazıyı okuyunca, önce kendi çözümümü yapıp yalnızca takıldığımda ya da fikre ihtiyaç duyduğumda önceki örneklere bakma fikrine daha çok yaklaştım
    Öte yandan yakın zamanda çıkan Clojure belgeselini izleyince, Rich Hickey sanki uzun süre önceki çalışmaları, makaleleri ve başka dilleri derinlemesine inceledikten sonra işe koyulmuş gibi görünüyordu
    Ama o kişi daha önce zaten başka diller de yapmıştı; yani daha büyük resim yine yaparak öğrenmekten başlıyor
    Belki de çok uzun süre sadece düşünmek yerine önce yapmalı, pratikte dersler biriktirmeli ve duvara tosladıktan sonra daha derin araştırmanın gerekli hale gelmesini beklemeli

  • Son tarih koyunca scope creep sorununun büyük kısmı çözülüyor
    Benim deneyimimde game jam ya da programlama yarışmaları gibi sert deadline'ı olan projeleri bitirmek daha kolay; ucu açık projeleri ise tamamlamak çok daha zor
    Bu, C++ standardının da istenen tüm özellikler hazır olana kadar beklemek yerine neden her 3 yılda bir yayımlandığıyla benzer bir mantık gibi geliyor
    https://news.ycombinator.com/item?id=20428703

  • Yazı ilginçti ama yazarın düşünceleri biraz dağınık saçılmış gibi geldi

    • Bence buradaki asıl mesele sonuçta scope creep
    • Bu, belirli bir konuyu keskin biçimde işleyen bir blog yazısından çok, bu kişiyi takip eden okurlara gönderilen bir newsletter güncellemesi gibi
  • Scope creep altında ezildiğini söyleyen birine göre, yazının sonunda her konuda bir sürü bağlantı olacak kadar inanılmaz fazla şey yapan biri gibi görünüyor
    Sonuçta öğrenmeyi ve farklı şeyler denemeyi gerçekten seven bir tip gibi; rabbit hole'lara dalma sürecinin kendisi zihnini keyifli biçimde uyarıyor olmalı

  • Tek başına bir şeyler yapan biri olarak bana çok yardımcı olan bir farkındalık oldu
    Zorunlu soyutlama gibi görünen şeylerin çoğu aslında sadece adı değiştirilmiş scope creep'miş
    Her yeni özelliğe flag eklerken kodumda bir örüntü gördüm ve bir kural koydum
    Özellikleri, flag-off davranışı için test yoksa yayımlamamaya karar verdim
    Böylece flag'leri bir kaçış kapısı değil, ürünün bir parçası olarak görmeye başladım; backlog'daki üç özellik de böyle düşünmeye başlayınca doğal biçimde ortadan kayboldu

  • Aşırı planlama ve scope creep'in sorun olduğu doğru, ama ters yöne savrulup aşırı doğaçlama geliştirme yapmaktan da kaçınmak gerek
    En başarılı projelerimden bazılarında, gerçekten çalışan yazılımı yapmadan önce veriyi modelleyerek özelliklerin çoğunu önceden planlayıp gözden geçirmiştim
    O aşamada neyin fazla olduğunu anlamak çoğu zaman zordur; benim ya da kullanıcıların isteyebileceği özellikleri çıkarırsan daha sonra kodun çekirdeğini ciddi biçimde yeniden tasarlamak için çok zaman harcarsın
    Tersine, yanlış tahmin edersen proje fazla büyür ve buna scope creep demeye başlarsın
    Sonuçta bu karar, alanı ne kadar iyi bildiğine bağlı
    Alanı sandığından az biliyorsan çok yeniden çalışma çıkar, sandığından iyi biliyorsan da aslında daha büyük gidebilecekken baby step'lerle vakit kaybetmiş olursun
    Hangi yöne gidersen git bir miktar pişmanlık kalıyor; bu yüzden sonunda büyük ölçüde bir muhakeme meselesi gibi geliyor

    • İdeal yöntem, analiz aşamasında yeterince zaman harcayıp zihnini doğru bağlamla doldurmak, ama uygulamaya geçince aşırı tasarlanmış çözümleri bırakıp eline gelen en doğrudan şeyi yapmaya hazır olmak gibi geliyor
      Batık maliyet yanılgısına düşmemek gerek; doktora düzeyinde bir konuyu birkaç saat araştırmış olman onu projede mutlaka kullanman gerektiği anlamına gelmez
      Şu anki probleme tam uymuyorsa rahatça çöpe atmak en doğrusu
    • Fazla yanlış yaparım diye endişelenme; önce dene, gerekirse sonra ayarlarsın