Hindley-Milner Tip Çıkarımı: Tip Yazmadan Tip Güvenliği

Bir fonksiyon yazdığınızı, hiçbir parametreye tip eklemediğinizi ve derleyicinin yine de bütün tip hatalarını yakaladığını düşünün. Üstelik derleyici yalnızca kodun doğru olup olmadığını söylemekle kalmasın, mümkün olan en genel tipi de keşfetsin! Hindley-Milner, yani HM tip sistemi, fonksiyonel programlama dünyasının bu etkileyici numarasını matematiksel olarak gerçekleştirir.

Devamı...

Gale-Shapley Algoritması: Kararlı Eşleştirmenin Matematiği

gale-shapley-algoritmasi-68

Bir grup doktoru hastanelere, öğrencileri üniversitelere veya kullanıcıları tercihlerine göre oyun sunucularına yerleştirdiğimizi düşünelim. Herkesin bir tercih listesi var ve bazı eşleşmeler diğerlerinden daha cazip. Rastgele seçim yapmak kolaydır; zor olan, kimsenin mevcut eşini bırakıp başka biriyle karşılıklı olarak eşleşmek istemediği kararlı bir sonuç bulmaktır. İşte Gale-Shapley algoritması bu sosyal dramayı düzenli, kanıtlanabilir ve verimli bir sürece dönüştürür.

Devamı...

Dinic Algoritması: Katmanlı Ağlarla Maksimum Akışı Hızlandırmak

Bir boru hattından taşınabilecek suyu, bir ağın kaldırabileceği veri trafiğini veya depodan mağazalara gönderilebilecek ürün miktarını hesaplamak istediğimizi düşünelim. Bu problemlerin ortak noktası, belirli kapasitelere sahip bağlantılardan kaynaktan hedefe mümkün olan en büyük akışı göndermektir. Dinic algoritması, katmanlı ağ fikrini kullanarak bu maksimum akışı verimli biçimde bulur.

dinic-algoritmasi-katmanli-67

Devamı...

Digit DP ile Dev Sayı Aralıklarında Basamak Basamak Sayma

Bir aralıkta belirli özelliklere sahip kaç sayı bulunduğunu hesaplamak bazen göründüğünden çok daha zordur. Örneğin, $1$ ile $10^{18}$ arasında rakamları toplamı 42 olan veya içinde hiç 7 geçmeyen sayıları tek tek kontrol edemeyiz. Digit DP, yani basamak dinamik programlama, tam burada devreye girerek sayıları değil, sayıların basamaklarında oluşabilecek durumları sayar.

digit-dp-ile-31

Devamı...

Çöp Toplama Arenası: Mark-Sweep ve Nesil Bazlı GC

Program çalışırken oluşturulan her nesne sonsuza kadar yaşamaz. Bir kullanıcı oturumu kapanır, geçici liste işini bitirir veya fonksiyon yerel değişkenleriyle vedalaşır. Bu nesnelerin kapladığı belleği otomatik olarak geri kazanan mekanizmaya çöp toplayıcı ya da GC (Garbage Collector) denir. Ancak bellekteki çöpleri bulmak, mutfaktaki çöp kutusunu boşaltmak kadar basit değildir: Önce hangi nesnenin gerçekten sahipsiz kaldığını anlamak gerekir.

Devamı...

SSA Formu: Derleyiciler Kodumuzu Neden Yeniden Yazar?

Yazdığımız kod derleyiciye ulaştığında değişmez bir kutsal metin gibi korunmaz. Tam tersine; parçalanır, sadeleştirilir ve analiz edilmesi daha kolay biçimlere dönüştürülür. Bu dönüşümlerin en önemlilerinden biri Static Single Assignment, kısaca SSA formudur. SSA sayesinde derleyici, her değerin nerede üretildiğini daha rahat görür ve kod üzerinde güvenli optimizasyonlar yapabilir.

ssa-formu-derleyiciler-19

Devamı...

Smalltalk: Modern Nesne Yönelimli Programlamanın Fikir Laboratuvarı

Bugün sınıflardan, nesnelerden veya kullanıcı arayüzlerinden söz ederken kullandığımız birçok kavramın izi Smalltalk’a çıkar. Xerox PARC’ta Alan Kay, Dan Ingalls, Adele Goldberg ve ekip arkadaşları tarafından geliştirilen Smalltalk, nesne yönelimliliği yalnızca bir programlama tekniği olarak değil, bilgisayarla iletişim kurmanın bütüncül bir modeli olarak ele aldı.

smalltalk-modern-nesne-15

Devamı...

Sekiz Komutla Sonsuz Hesap: Brainfuck ve Esolang Dünyası

Bir programlama dilinden değişkenler, fonksiyonlar ve okunabilir hata mesajları bekliyorsanız Brainfuck sizi biraz üzebilir; hatta adı üstünde, zihninize küçük bir düğüm atabilir. Yalnızca sekiz komuttan oluşan bu deneysel dil, programlamanın süslü araçlarını kaldırıp geriye hesaplamanın çıplak mekanizmasını bırakır. Brainfuck ve diğer ezoterik programlama dilleri, yani esolang‘lar, bilgisayara ne yaptırabileceğimiz ile bunu ne kadar anlaşılır ifade edebileceğimizin tamamen farklı meseleler olduğunu gösterir.

Devamı...

Racket ile Kendi Programlama Dilini Tasarlamak: DSL Mantığı

Bir robotu hareket ettirmek için yüzlerce satırlık genel amaçlı kod yazmak yerine move 5 ve turn left gibi ifadeler kullanabilseydik nasıl olurdu? Etki alanına özgü dil, yani DSL (Domain-Specific Language), belirli bir problem alanını doğal ve güvenli biçimde ifade etmek için tasarlanır. Racket ise güçlü makro sistemi, sözdizimi nesneleri ve #lang mekanizması sayesinde küçük bir dili sıfırdan üretmek için adeta programlama dilleri laboratuvarıdır.

racket-ile-kendi-62

Devamı...

LLVM IR’a Giriş: Programlama Dilleri Arasında Evrensel Bir Köprü

llvm-ira-giris-92

Bir programlama dilinde yazdığımız kodun onlarca farklı işlemci ve işletim sisteminde çalışabilmesi küçük bir mucize gibi görünebilir. LLVM IR (Intermediate Representation), bu mucizenin arkasındaki önemli oyunculardan biridir. Kaynak dil ile makine kodu arasında ortak bir durak oluşturarak dil tasarımcılarının her donanım için ayrı derleyici yazma çilesini büyük ölçüde azaltır.

Devamı...

LL ve LR Ayrıştırma: Gramerler Neden Çakışır?

Bir derleyici kaynak kodu okurken yalnızca anahtar kelimeleri tanımakla yetinmez; bu kelimelerin hangi yapıyı oluşturduğunu da çözmeye çalışır. İşte ayrıştırıcıların görevi budur. LL ve LR yöntemleri aynı token dizisine farklı yönlerden yaklaşır. Gramer yeterince açık değilse ayrıştırıcı bir yol ayrımına gelir ve meşhur “çakışma” ortaya çıkar.

Devamı...

Lexer–Parser Mimarisi: Kaynak Kod Nasıl Anlam Kazanır?

Bilgisayar için toplam = 5 + 3 ifadesi başlangıçta yalnızca karakterlerden oluşan bir dizidir. İnsan gözü bunun bir değişkene toplama sonucunu atadığını hemen anlar; işlemciyse büyücü değildir. Karakterlerin önce sözcüklere, ardından yapısal bir modele dönüştürülmesi gerekir. İşte lexer ve parser, kaynak kod ile anlam arasındaki bu köprünün iki ana mimarıdır.

Devamı...

F# ile .NET Dünyasında Fonksiyonel Programlama

F#, .NET ekosisteminin güçlü araçlarını fonksiyonel programlama yaklaşımıyla buluşturan, kısa fakat etkileyici kodlar yazmayı sağlayan bir dildir. C# ile aynı çalışma zamanını paylaşmasına rağmen problemlere farklı bir gözlükle bakar: Veriyi sürekli değiştirmek yerine dönüştürür, işlemleri küçük fonksiyonlara böler ve olası durumları tür sistemiyle açıkça ifade eder. Kısacası F#, kodun içine biraz matematik, biraz düzen ve bolca huzur katar.

f-ile-net-20

Devamı...

Az Sözcük, Çok İş: Forth ve Yığın Tabanlı Programlamanın Minimalist Felsefesi

Modern programlama dünyası katmanlar, paket yöneticileri ve devasa çalışma zamanlarıyla doluyken Forth, küçük bir sırt çantasıyla yola çıkan gezgin gibidir. Sözdizimi son derece azdır; veriler bir yığın üzerinde dolaşır ve program, küçük sözcüklerin yan yana gelmesiyle büyür. İlk bakışta tuhaf görünen bu yaklaşım, bilgisayarın yaptığı işi şaşırtıcı ölçüde görünür kılar.

Devamı...

APL ve BQN: Dizi Programlamada Tek Satırın Şaşırtıcı Gücü

Bir listedeki sayıları dönüştürmek, süzmek ve özetlemek için kaç satır kod gerekir? Geleneksel bir dilde döngü, sayaç ve geçici değişkenler devreye girebilir. APL ve onun modern akrabası BQN ise aynı problemi birkaç sembolle anlatır. İlk bakışta uzaylı alfabesine benzeyen bu yaklaşımın sırrı, tek tek elemanlarla değil dizilerin bütünüyle düşünmesidir.

apl-ve-bqn-24

Devamı...

WebAssembly ile Tarayıcıda Native Hıza Yaklaşmak

Bir web sayfasının görüntü işlemek, fizik simülasyonu çalıştırmak veya milyonlarca veri noktasını analiz etmek için kullanılması geçmişte pek gerçekçi değildi. JavaScript motorları çok hızlandı; ancak C, C++ ve Rust gibi sistem dilleriyle geliştirilen ağır algoritmalar söz konusu olduğunda tarayıcıların yeni bir oyuncuya ihtiyacı vardı: WebAssembly, kısa adıyla WASM. Bu teknoloji, tarayıcıyı yalnızca belge gösteren bir uygulamadan yüksek performanslı bir çalışma platformuna dönüştürüyor.

Devamı...

OCaml ile Tip Çıkarımı: Derleyici Tipinizi Nasıl Tahmin Ediyor?

OCaml’de bir değişkenin veya fonksiyonun tipini çoğu zaman yazmayız; buna rağmen derleyici hatalı kullanımları daha program çalışmadan yakalar. Bu durum sihir gibi görünse de arkasında sistematik bir mekanizma vardır: tip çıkarımı. Derleyici aslında tipimizi rastgele tahmin etmez; ifadelerden kısıtlar üretir, bu kısıtları çözer ve mümkün olan en genel tipi bulur.

ocaml-ile-tip-66

Devamı...

Nim Dili: Python Sözdizimiyle C Hızı Vaadi Gerçek mi?

Nim, ilk bakışta Python’ın derlenmiş ve spor salonuna yazılmış kuzeni gibi görünür: girintili, temiz bir sözdizimi sunar; ancak kodu doğrudan yorumlamak yerine çoğunlukla C’ye çevirip yerel makine koduna derler. Peki “Python rahatlığı, C hızı” sloganı gerçeği mi anlatıyor, yoksa pazarlama departmanının kahvesi biraz fazla mı sertti?

Devamı...

Lisp ve Scheme’de Kod Veridir: Homoiconicity Neden Hâlâ Önemli?

Bir Lisp programına ilk kez bakanların ortak tepkisi genellikle şudur: “Bu kadar parantez gerçekten gerekli mi?” Bir süre sonra parantezlerin süs değil, dilin temel fikrinin görünür hâli olduğu anlaşılır. Lisp ailesinde programlar, dilin sıradan veri yapılarıyla temsil edilir. Kısacası kod ile veri aynı kıyafeti giyer; buna homoiconicity denir.

Devamı...

Işın İzleme: Piksellerin Arkasındaki Optik Fizik ve Algoritmalar

isin-izleme-piksellerin-72

Bir ekrandaki parlak metal, saydam cam veya yumuşak gölge yalnızca estetik bir hile değildir. Işın izleme, ışığın gerçek dünyadaki davranışını matematiksel bir modele dönüştürerek her pikselin rengini hesaplar. İşin eğlenceli tarafı şudur: Algoritma, doğadaki sayısız fotonu ileri doğru takip etmek yerine kameradan sahneye ters yönde ışın göndererek yalnızca görüntüye katkı sağlayan yolları araştırır.

Devamı...