- Arthur Whitney'nin yazdığı 50 satırlık K dili yorumlayıcısı C kodunu analiz edip, onun kendine özgü kodlama stilini yorumlayan bir kayıt
- Kodda makro tabanlı sıkıştırılmış sözdizimi, standart dışı C genişletmeleri, örtük argüman kullanımı gibi sıradan C kodundan farklı birçok deneysel yapı bulunuyor
- Yazar, her makro ve fonksiyonun anlamını bizzat çözümleyerek APL ailesi dillerin felsefesini ve kod yoğunluğunun artılarını ve eksilerini inceliyor
- Kodun avantajları olarak kısa uzunluk ve yüksek ifade gücü, dezavantajları olarak ise standart dışı sözdizimi ve okunabilirlik kaybı belirtiliyor
- Sonuç olarak bu kod, “kısa yazma”dan çok problemi tamamen anladıktan sonra kod yazma düşünce biçiminin önemini gösteren bir örnek olarak değerlendiriliyor
Arthur Whitney ve kodu
- Arthur Whitney, A, K, Q dilleri ile kdb, Shakti veritabanlarını tasarlayan bir bilgisayar bilimci
- kdb, finans sektöründe kullanılan ultra hızlı bir zaman serisi veritabanı; Shakti ise bunun daha hızlı bir sürümü olarak 1 trilyon satır ölçekli veri kümelerini işlemek üzere tasarlandı
- Onun dilleri, APL'den güçlü biçimde etkilenmiş dizi tabanlı diller olup sadelik ve matematiksel ifade gücünü öne çıkarıyor
- Yazının odağı finans uygulamaları değil, Whitney'nin yazdığı C kodunun kendine özgü stilini analiz etmek
50 satırlık K yorumlayıcısının yapısı
- Açık ksimple deposunda, Whitney'nin birkaç gün içinde yazdığı yaklaşık 50 satırlık bir C yorumlayıcısı yer alıyor
- Kodun özü
a.h ve a.c olmak üzere iki dosyadan oluşuyor; öne çıkan özellikleri arasında makrolarla fonksiyon tanımlarını kısaltma ve pointer'ları tamsayı gibi kullanma yapısı var
typedef char*s,c; ifadesiyle s bir string pointer'ı, c ise karakter türü olarak tanımlanıyor
s Q=(s)128;, pointer'ın tamsayı gibi kullanılmasına bir örnek; kod genelinde Q hata durumunu gösteren özel bir değer olarak kullanılıyor
({e;}) biçimindeki statement expression ile ?: operatörü gibi GCC genişletmelerine ait sözdizimleri yoğun biçimde kullanılıyor
Başlıca makro ve fonksiyonların anlamı
#define _(e...) ({e;}) : birden fazla ifadeyi tek bir expression içinde toplayan makro
#define i(n,e) : döngüleri kısaltan ifade; for döngüsünü tek satırda yazıyor
#define Q(e) vb. yapılar hata işleme makroları; Qr, Qd, Qz sırasıyla rank, domain ve henüz uygulanmamış hata döndürüyor
_s, _i, f, F makroları fonksiyon bildirimlerini sadeleştiriyor ve örtük olarak x, a argümanlarını kullanıyor
ax, ix, nx gibi yapılar veri türü belirleme ve indeksleme makroları; ax, “x bir atom mu?” sorusunu yanıtlıyor
f(w,write(1,ax?&x:x,ax?1:strlen(x));x) bir çıktı fonksiyonu; atomsa karakter olarak, vektörse string olarak yazdırıyor
Yorumlayıcının çalışma biçimi
m(x) fonksiyonu bellek ayırma ve uzunluk bilgisi içeren pointer üretme işini yapıyor; vektörlerin azami uzunluğu 255 bayt
g(a,v) makrosu atom/vektör işlemlerini birleşik biçimde ele alıyor; not, sub, At, _A gibi fonksiyonlar bunun üstüne kuruluyor
G(f,o) makrosu ikili operatör fonksiyonlarını otomatik üretiyor; <, ==, +, *, &, | gibi işlemleri destekliyor
cat, rev, cnt, Tak gibi yapılar vektör işleme fonksiyonları; rev, ters indeks üretmek için ind fonksiyonunu kullanıyor
e() fonksiyonu özyinelemeli değerlendirici; string'i sağdan sola okuyarak tek karakterli değişkenleri, sayıları ve operatörleri işliyor
main() girdi alıp e() ile değerlendirdikten sonra sonucu yazdıran bir REPL döngüsü biçiminde çalışıyor
Kod stiline dair değerlendirme
- Avantajlar
- Birleştirilebilir makrolardan oluşan özlü bir ilkel işlem kümesi
- Kısa kod uzunluğu sayesinde tüm mantığın kaydırma yapmadan tek bakışta görülebilmesi
- Yüksek yoğunluklu ifade ile kodun mantıksal yapısının sıkıştırılması
- Dezavantajlar
char*'ı tamsayı gibi kullanan anlamsız tür işleme yaklaşımı
- ASCII kodlarının doğrudan kullanımı, karmaşık üçlü operatörler, standart dışı sözdizimi gibi nedenlerle düşen okunabilirlik
- Örtük argümanlar ve kısa değişken adları yüzünden niyetin anlaşılmasının zorlaşması
- Nötr unsurlar
- GCC'ye özgü sözdizimi (
?:, statement expression) ilginç olsa da taşınabilirliği azaltıyor
- Örtük argüman kullanımı küçük ölçekli kodda faydalı olabilir, ama büyük kod tabanlarında kafa karışıklığı yaratabilir
- Kısa adlar alışıldığında verimli olabilir, ancak anlam aktarma gücü zayıf kalıyor
Sonuç ve çıkarımlar
- Bu kod sadece “kısa yazma”yı değil, problemi tamamen anladıktan sonra kod yazma düşünce biçimini gösteriyor
- Whitney'nin kodu, zaten tamamlanmış bir matematiksel modelin koda aktarılmış hali, yani “düşüncenin koda dökülmüş sonucu”
- Yazar, kendisinin normalde problemi kodun içinde çözmeye çalışma alışkanlığını sorguluyor ve
bundan sonra kod yazmadan önce kavramsal modelleme ve düşünceyi netleştirmenin önemini vurguluyor
- Sonuçta bu deney, kod okuma becerisini geliştiren ve kod yoğunluğu ile düşünsel açıklık arasındaki dengeyi araştıran bir tecrübe olarak özetleniyor
Gelecekteki deney fikirleri
- Yorumlayıcıyı genişletmeye yönelik alıştırma önerileri:
- Kayan noktalı vektör desteği
- 255'ten fazla öğenin işlenmesi
- Birden fazla basamaklı sayılar ve değişken adları
- Dizi literal'leri ve boşluk yoksayma
- Bellek yönetimi ve hata gösterimi ekleme
- Eksik uygulanmış fonksiyonları tamamlama
- Bu genişletmeler, Whitney tarzı kod stilini korurken onu gerçekten kullanılabilir bir dile dönüştürme deneyi olabilir
1 yorum
Hacker News görüşü
Bu koddaki makrolar ortak işlemleri sıkıştırmak için var Ben önce J Incunabulum’u okuyup sonra bu koda baktım; C’ye aşina programcılar ortasından okumaya başlarsa baştaki makro tanımları kafa karıştırıcı olabilir Makrolar birbirinin üzerine inşa edildiği için kod hızla soyutlama merdivenini tırmanıyor Özellikle
Iteratemakrosunu (i) seviyorum; uzun döngüleri tek harfe indiriyor Bu kadar yoğun kodun okunmasının zor olmasının nedeni, birkaç düzine satır içinde çok sayıda soyutlama yaratıp bunları hemen kullanması Bu yüzden harf harf, yavaşça okumak gerekiyor Yüzlerce ince dosyadan oluşan büyük bir kod tabanında çalışmış biri olarak, bu kadar uç düzeyde sıkıştırılmışlık bana aksine ferahlatıcı geliyorgrep *.[ch]ile doğrudan arama yapılabilen yapıları seviyorum Özellikle Java projelerinde çok fazla küçük ve içeriği zayıf dosya oluyor; bir şey bulmak zorlaşıyor IDE varsa daha iyi olabilir ama ben kullanmıyorum Whitney bir röportajda tüm kodu tek sayfaya sığdırmak istediğini söylemişti ve onun “IDE”si Windows konsolu ve Notepad imişArthur Whitney’nin C kodunu anlamak için önce APL ailesinden bir dil öğrenmek gerekiyor Aksi halde sadece tuhaf bir C tarzı gibi görünüyor Whitney, C’yi APL gibi kullanmaya çalışıyor Boşluksuz, tek harfli isimler kullanan ve tek satırlık fonksiyonlardan oluşan bu stil APL’de de var Bu, Pascal programcısının
#define begin {gibi şeyler yazmasına benziyor ama Whitney çok daha özgün#define begin {yapmasına benziyor” sözüne, “Ha, Stephen Bourne gibi yani” diye şaka yapılıyorShakti’yi ararken Wikipedia bağlantısının
k.nycadresine yönlendiğini gördüm; sayfada sadece tek harf ‘k’ vardı Kaynağa bakınca gerçekten yalnızca `k` vardı Bu, HTML sürümü bir Whitney usulü minimalizm gibi — gereksiz her şey atılmış, geri kalanı derleyicinin örtük biçimde halletmesine bırakılmış
k
Bu blog yazısı, Whitney’nin kodlama stiline dair değerlendirmeden bağımsız olarak harika bir analiz yazısı Yazarın bunu 8 saatte yazmış olmasına rağmen derinlikliydi; özellikle sonuç bölümü çok etkileyiciydi Orijinal bağlantı
Stephen Bourne’un C’yi Algol benzeri hale getirme çabasını hatırlatıyor mac.h örneği ve expand.c örneği benzer bir his veriyor
Her alanda “best practice” vardır ama bu sadece ortalama durumlarda iyi çalışır Bazı özel durumlarda tam tersine gitmek daha iyi olabilir Sonuçta kolektif bilgelik varsayılan kabul edilebilir ama insan kendi başına düşünmeye başlayınca aradaki boşlukları görür
Kod konusunda saldırganlaşmadan dengeli bir bakış açısı sunmasını beğendim Zevkle okudum; sonra tekrar dönüp okuyacağım
Böyle bir kodlama stilinin belirli bir paradigma olup olmadığını merak ettim Gerçek projelerde buna benzer kodu neredeyse hiç görmedim; “business card ray tracer” gibi istisnalar dışında Whitney’nin yarattığı J dilinin kaynak kodu da benzer şekilde aşırı derecede sıkıştırılmış bir stil taşıyor
Şu makro tanımlarına bakınca