function live(day) {
  breathe();
  eat();
  work();
  sleep();
  live(day + 1);
}

Yukarıdaki fonksiyonu inceleyin. İlk bakışta basit bir recursion (özyineleme) örneği. Bir fonksiyon, kendi görevlerini yerine getirdikten sonra kendini tekrar çağırıyor. Nefes al, ye, çalış, uyu, tekrarla. Sonsuza dek.

Ama bu fonksiyonda bir sorun var. Base case yok. Bu fonksiyon ne zaman duracağını bilmiyor. Durmak için bir koşul tanımlanmamış. Teoride sonsuza kadar çalışmalı. Pratikte ise çağrı yığını (call stack) dolacak ve sistem bir Stack Overflow hatası verecek.

İnsan hayatı da tam olarak böyle bir recursion'dır. Ve ölüm, bizim base case'imizdir.

Stack Overflow: Sonluluğun Zarureti

Bilgisayar biliminde her recursion'ın bir base case'e ihtiyacı vardır. Bu, döngünün durma koşuludur. Base case olmadan recursion sonsuz bir döngüye girer ve sistem çöker. Bu, tasarım hatası değildir; fiziksel bir zorunluluktur. Hiçbir makine sonsuz hafızaya sahip değildir.

İnsan yaşamında ölüm de benzer bir zorunluluktur. Eğer insanlar ölümsüz olsaydı, yani yaşam fonksiyonumuzun base case'i olmasaydı ne olurdu? İlk bakışta harika görünür: sonsuz zaman, sonsuz deneyim, sonsuz öğrenme.

Ama biraz daha düşündüğünüzde, sonsuz zamanın aslında zamanı anlamsızlaştıracağını fark edersiniz. Bir şeyi "yarın" yapabilme lüksünüz sonsuza kadar uzadığında, o şeyi "bugün" yapmak için hiçbir motivasyonunuz kalmaz. Aciliyet duygusu yok olur. Ve aciliyet olmadan, anlam da buharlaşır.

Tıpkı bir deadline'ı olmayan bir yazılım projesinin asla bitmeyeceği gibi, sonu olmayan bir yaşam da asla gerçekten "yaşanmaz". Ölüm, hayata deadline (son teslim tarihi) koyar. Ve biz insanlar, ne kadar nefret etsek de, deadline'larla çalışırız.

Fibonacci ve Doğanın Özyinelemesi

Doğa, recursion'ın en zarif derleyicisidir (compiler). Fibonacci dizisi — 1, 1, 2, 3, 5, 8, 13, 21... — bir özyineleme formülüdür. Her sayı, kendinden önceki iki sayının toplamıdır. Ve bu dizi, ayçiçeğinin spiral yapısında, deniz kabuklarının kıvrımlarında, galaksilerin kollarında, hatta insan kulağının iç yapısında karşımıza çıkar.

DNA replikasyonu bir recursion'dır: Hücre kendini kopyalar, kopya kendini kopyalar, sonsuza dek... ta ki organizma ölene kadar (base case). Evrim de bir recursion'dır: Bir tür kendini bir sonraki nesle aktarır, o nesil kendini aktarır, sonsuza dek... ta ki o tür soyunu tüketene kadar (base case: yok oluş).

Doğa, base case'in kaçınılmazlığını milyonlarca yıl önce kabul etmiş ve bunu bir felaket değil, bir tasarım prensibi olarak benimsemiştir. Ölüm, doğanın garbage collector'ıdır (çöp toplayıcı). Kullanılmayan kaynakları serbest bırakır ki yeni süreçler çalışabilsin.

Tail Call Optimization: Verimli Yaşamak

Fonksiyonel programlamada "kuyruk çağrısı optimizasyonu" (tail call optimization) adında bir teknik vardır. Normal recursion'da her çağrı stack'e yeni bir katman ekler ve bu sonunda taşmaya yol açar. Ama eğer recursive çağrı fonksiyonun en son işlemi olarak yapılırsa, derleyici stack'e yeni katman eklemek yerine mevcut katmanı yeniden kullanabilir. Fonksiyon sonsuz kez çağrılabilir ama stack asla taşmaz.

Bu, verimli yaşamanın güzel bir metaforudur. Her gün yeni bir yük, yeni bir endişe, yeni bir pişmanlık biriktirmek yerine; günü yaşayıp, o günün yükünü bırakıp, ertesi güne temiz bir stack ile başlamak. Dünün hatalarını bugüne taşımamak. Stack'inizi şişirmemek.

Paramediklikte buna "nöbet teslimi" denir. Nöbetiniz bittiğinde, o gün yaşadığınız her vakayı — kurtardığınız hastaları da, kaybettiklerinizi de — bir sonraki ekibe "teslim" edersiniz. Ve evinize, boş bir stack ile dönersiniz. Bu, duygusal olarak kolay değildir ama hayatta kalmak için zorunludur.

return;

Her güzel fonksiyonun bir return ifadesi vardır. Her güzel hayatın da bir sonu. Ve tıpkı iyi yazılmış bir recursive fonksiyon gibi, önemli olan sonsuz kez çalışmak değil, her çağrıda anlamlı bir iş yapmak ve doğru zamanda, zarif bir şekilde durmaktır.

function live(day) {
  if (day > MAX_DAYS) return memories;
  
  breathe();
  love();
  create();
  sleep();
  
  return live(day + 1);
}

Base case'iniz her ne olursa olsun, önemli olan her iterasyonda memories dizisine eklediğiniz değerlerdir. Sonsuza kadar çalışan ama hiçbir şey üretmeyen bir fonksiyon, doğru zamanda durup güzel bir sonuç döndüren fonksiyondan her zaman daha başarısızdır.