November 14, 2021

Merhaba,

Bu pazar yaptığımız Zoom toplantısında yazılabilecek çok şey var. Ama genelde Ali Çehreli'nin, Berlin'de yaptığı Dconf 2016 sunumu çerçevesinde ilerledik...

Çok fazla uzatmadan 30. sayfasında bahsedilen konu örneğinin son halini paylaşmak istiyorum. Eminim üzerine söylenebilecek şeyler vardır:

/* Kodu şuradan da çalıştırabilirsiniz:
 * https://code.dcoder.tech/files/code/6190cfed29f6a005aa26baf7/fibfiber
 *
 * Konu için şu sayfayı okuyun:
 * http://ddili.org/ders/d/fiberler.html
 */
import std.stdio, std.range;
import std.concurrency;

class FibonacciSerisi(T) {
    Generator!T seri;

    this() {
        seri = new Generator!T(&series);
    }

    void series() {
        T baştaki = 0;
        T sonraki = 1;

        while (true) {
            yield(baştaki);

            const ikiSonraki = baştaki + sonraki;
            baştaki = sonraki;
            sonraki = ikiSonraki;
        }
    }
}

void main() {
    enum limit { min = 48, max = 94 }
    // limit.min == fib(uint.max), limit.max == fib(ulong.max)
	
    with(new FibonacciSerisi!uint) {			
        auto fib = seri.take(limit.min);
        typeof(fib).stringof.writeln;
        writefln("Serinin son 2 elemanı:\n%(%s\n%)\n",
                                  fib.array[$ - 2..$]);
    }

    uint.max.writeln(" == uint.max, toplamlarından küçük\n",
                         "ulong ile yeniden deneyelim...\n");

    auto r = limit.max - limit.min;

    with(new FibonacciSerisi!ulong) {
        auto fib = seri.take(limit.max);
        typeof(fib).stringof.writeln;
        writefln("Serinin son 2 elemanı:\n%(%s\n%)\n",
                                  fib.array[$ - r..$]);
    }
    ulong.max.writeln;
 }
 /* test için lütfen deneyin:
  * dmd fibFiber.d -unittest
  */
 unittest
 {
    ulong baştaki, sonraki = 1;
		
    foreach(_; 0..93) {
       const ikiSonraki = baştaki + sonraki;
       baştaki = sonraki;
       sonraki = ikiSonraki;
    }
    assert(baştaki == 12200160415121876738);
}

Örnek tabi başlangıç için karışık gelebilir. O yüzden konuya hakim değilseniz, basit sürümün yer aldığı ders sayfasından başlamalısınız.

Çok uzatmak istemiyorum; özetle 50 satırlık bir program ve ilk yarısı zaten bildiğimiz şeyler! Burada işi yapan işlevin (series) Generator ile kurup emanet ediyoruz. O da tek bir thread üzeriden, CPU tarafından atanan görevini bitirmeden aralıklı olarak iş yaptırıyor.

Bunu da yield() ile kontrol ediyoruz. Sonsuz döngü yanıltmasın! çünkü sürekli döngü bölünüyor, iş yaptırılıyor ve sonuç teslim ediliyor. Yani sanki take() ile aralık üretilirken while() ile arasında mekik dokunuyor.

Tuhaf bir şey ama hala anlamaya çalışıyorum. Hoca daha yetkin bir şekilde ifade edecektir...:)

Başarılar...