April 09, 2012

Merhaba Zafer,

Senin yazdığın şekilde de denemeye başladım. Sonuçları 24 saat sonra ifade edeceğim inşaallah...

Aslında bu kodun A ile B veya S ile Z şeklinde yazılmasının hiç bir mahsuru yok. Hatta fırın da yanmayabilir ki önemli olan başta, ortada ve belki sonda karışık bir şekilde (rasgele değil ranfomize fonksiyonundan şimdilik uzak durmalı) herhangi bir işlevin Thread özelliğiyle çağrılması bize bu yapının inceliklerini daha iyi anlamamızı sağlayabilir. Ama spawn() yoluyla, yani dolaylı bir şekilde Thread'ların oluşturulması beni rahatsız ediyor. Henüz std.concurrency.d'*****' alternatifini yapamam da beni iki kat rahatsız etmekte...:)

'*****' (sdb dizininde concurrency.d dosyası oluşturdum ve sdb.concurrency şeklinde import ediyorum...)

Bence D'nin kesinlikle Sean'nın yazdığı şu sınıftan'******' daha iyi bir şeye ihtiyacı var ya da bu sınıfı kullanmadan Thread'ları birbirleriyle haberleştirmeyi öğrenmeye benim ihtiyacım var. Ama ben bunların nasıl yapılacağını henüz bilmiyorum...:(

'******' (aslında şu mailbox mantığı gayet güzel, bir de sınıfı import etmeden doğrudan denemeli)

Başarılar...

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 09, 2012

Hiç derinlemesine düşünmedim ve kodu derlemedim bile ama böyle farklı bir tür tanımlamak tabii ki yararlı olur.

Hızlıca gördüklerim şöyle:

  1. _firinSicakligi ve _mevcutGazMiktari üzerinde açıklamalarda belirtildiği gibi kesin kısıtlamalar varsa bunları D olanakları ile de garantileyebiliriz. invariant blokları sınıfın mutlak değişmezliğini garanti eder:
class Firin
{
// ...
   invariant()
   {
       assert((_firinSicakligi >= 0) && (_firinSicakligi < 300));
       assert((_mevcutGazMiktari >= 0) && (_mevcutGazMiktari < 10_000));
   }
}

invariant blokları sözleşmeli programlamanın bir parçasıdır ve şu zamanlarda çağrılırlar:

  • Kurucu işlev sonunda; böylece nesnenin yaşamına tutarlı olarak başladığı garanti edilir.

  • Sonlandırıcı işlev çağrılmadan önce; böylece sonlandırma işlemlerinin tutarlı üyeler üzerinde yapılacakları garanti edilir.

  • public bir işlevden önce ve sonra; böylece üye işlevlerdeki kodların nesneyi bozmadıkları garanti edilir.

Böylece Firin nesnelerinin tutarsız durumda bulunmaları önlenmiş olur.

Ancak, program -release seçeneği ile derlendiğinde bütün assert'ler gibi bütün sözleşmeli programlama olanakları da (in, out, ve invariant blokları) koddan çıkartılırlar. (Bunun istisna: assert(false)'lar hiçbir zaman koddan çıkartılmazlar.)

Bu da bizi assert'lerde de yaşadığımız güç bir kararla karşı karşıya bırakır: Ne zaman assert kullanmalı, ne zaman hata atmalı? Bu soruyu yanıtlamak için sorulması gereken soru şu: nesne hiç kullanıcılar tarafından oluşturuluyor mu, yoksa yalnızca bu kütüphanenin veya programın kodları tarafından mı oluşturuluyor?

Eğer Firin türünü modülün arayüzüne koymuşsak, kullanıcıların Firin nesnelerini yanlış değerlerle oluşturmalarını invariant blokları ile engelleyemeyiz çünkü -release ile derlediklerinde invariant denetimleri yok olurlar.

O yüzden, eğer Firin modülün arayüzündeyse, ya invariant bloğunun yerine ya da onunla birlikte ayrıca kurucuya enforce() denetimleri de eklenmelidir:

import std.exception;
class Firin
{
// ...
   public this(int mevcutGazMiktari, int firinSicakligi)
   {
       enforce((firinSicakligi >= 0) && (firinSicakligi < 300),
               "Geçersiz fırın sıcaklığı");
       enforce((mevcutGazMiktari >= 0) && (mevcutGazMiktari < 10_000),
               "Geçersiz gaz miktarı");

       _mevcutGazMiktari = mevcutGazMiktari;
       _firinSicakligi = firinSicakligi;
   }

Tabii hata mesajı örneğin format() ile yanlış değeri de söyleyebilir.

Bilmeyenler için, enforce(), bir if ve throw deyimini sarmalayan bir kolaylık işlevidir. Temelde şu etkiye sahiptir ama std.exception modülündeki tanımı daha yetenekli:

void enforce(bool mantıksalİfade, lazy string mesaj)
{
   if (!mantıksalİfade) {
       throw new Exception(mesaj);
   }
}
  1. Geçersiz Hamuru değerlerine karşı da final switch daha uygun olabilir:
final switch (pizaHamuru)

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 09, 2012

Alıntı (Salih Dinçer):

>

Ama spawn() yoluyla, yani dolaylı bir şekilde Thread'ların oluşturulması beni rahatsız ediyor.

spawn()'ın başka işlevlerden farkı yok: bizim her iş parçacığı başlatırken tekrar tekrar yapmamız gereken işlemleri o hallediyor.

Alıntı:

>

Bence D'nin kesinlikle Sean'nın yazdığı şu sınıftan'******' daha iyi bir şeye ihtiyacı var ya da bu sınıfı kullanmadan Thread'ları birbirleriyle haberleştirmeyi öğrenmeye benim ihtiyacım var. Ama ben bunların nasıl yapılacağını henüz bilmiyorum...:(

'******' (aslında şu mailbox mantığı gayet güzel

Tabii mailbox mantığı yalnızca "güzel" değil. Mailbox kullanan (yani mesajlaşmaya dayanan) eş zamanlı programlama ile doğrudan veri paylaşımına dayanan eş zamanlı programlama arasında ölçülemeyecek kadar büyük bir fark var:

  • Mesajlaşmaya dayanan eş zamanlı programlama çok kolaydır. Programın nasıl işlediği konusunda kolayca mantık yürütülebilir.

  • Doğrudan veri paylaşımına dayanan eş zamanlı programlamada ise programın doğru yazılmış olduğu ispatlanamaz bile (çok basit programlar hariç).

O yüzden ölçülemeyecek kadar büyük fark diyorum. Birisinin doğru çalışacağından emin olamıyoruz bile. Ne kadar testten geçerse geçsin yine de program kilitlenebilir veya yanlış sonuçlar üretebilir. Şu yazıda ölümlerle sonuçlanmış hatalar da yer alıyor:

http://en.wikipedia.org/wiki/Race_condition

D'nin std.concurrency modülü modern programlamanın kabul ettiği mesajlaşmayı gerçekleştirir ve çok yakın bir süre önce yazılmış olduğu için de bu konudaki en iyi olarak kabul edilmiş olan arayüzlerden birisini kullanır.

Bunu destekleyen bir örnek de Microsoft'un CCR'ıdır:

http://msdn.microsoft.com/en-us/magazine/cc163556.aspx

O da heredeyse aynı D'deki mesajlaşma yöntemi benimsenmiştir.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 10, 2012

Alıntı (Salih Dinçer):

>

Hatta fırın da yanmayabilir ki önemli olan başta, ortada ve belki sonda karışık bir şekilde (rasgele değil ranfomize fonksiyonundan şimdilik uzak durmalı) herhangi bir işlevin Thread özelliğiyle çağrılması bize bu yapının inceliklerini daha iyi anlamamızı sağlayabilir. Ama spawn() yoluyla, yani dolaylı bir şekilde Thread'ların oluşturulması beni rahatsız ediyor.

Salih anladığım kadarıyla senin esas denemek istediğin kanal (thread) mekanizması o sebeple fırınla, kilerle yada diğer nesnelerle çok zaman harcamak istemiyorsun haklısın tabi ve diğer tarfatan bence proje küçük gibi görünsede aslında çok büyük, benim gördüğüm bir imalat hattının simülasyonunun yapılması ki bence bu gerçekten büyük bir iş :) Ben kendimce bir şeyler yazıyorum eğer işine yararsa sende projene ekleyebilirsin hayır ben başka bir yöntemle veya başka konuda devam edeceğim dersen yazdıklarım bana tecrübe kalır :)

Alıntı:

>

Ancak, program -release seçeneği ile derlendiğinde bütün assert'ler gibi bütün sözleşmeli programlama olanakları da (in, out, ve invariant blokları) koddan çıkartılırlar. (Bunun istisna: assert(false)'lar hiçbir zaman koddan çıkartılmazlar.)

Mesajın girişini okurken evet şimdi gerçekten yeni bir şey öğrendim dedim ama sonra bu kısma gelince sanki tahtaya birşeyler yazıp sonra silgi ile silmiş gibi oldum. Doğrusu invariant'ın ne işe yaradığı konusunda kafam karıştı, çünkü zaten üretimi tamamlanan programları bizler her zaman -release modunda derlemez miyiz? Bu olanaklar sadece programcı için hazırlarmış anlamına mı geliyor?

Alıntı:

>

O yüzden, eğer Firin modülün arayüzündeyse, ya invariant bloğunun yerine ya da onunla birlikte ayrıca kurucuya enforce() denetimleri de eklenmelidir:

Evet, enforce() ekledim ama işi biraz daha çeşitlendirmek adına property kullanımınıda pekiştirmek ve ileride sıcaklığın tekrar değişebileceği ve bunun için sadece kurucu ile sıcaklık ayarı yapılmasının kısıtlayıcı olduğunuda göz önüne alarak bir property ekledim. Ne dersiniz birde siz bakın bakalım hata veya eksikler neler? enforce yerine bir exception sınıfı tanımlamak daha iyi olabilir mi?

import std.stdio;
import std.concurrency;
import std.exception;
import core.thread;

enum Hamuru
{
   ince = 1,   // En çok sevdiğim :)
   orta,
   kalın
}

void main()
{
   writefln("Firin pisirme icin calistiriliyor ...");

   Firin pizaFirini = new Firin(5000, 200);

   pizaFirini.FiriniYakSicakligiAyarla();

   writefln("Firin pisirmeye hazir. Firin sicakligi : %s derece", pizaFirini.VerFirinSicakligi);
}


class Firin
{
   private int _firinSicakligi = 0;     // 0..300 birim sıcaklık arasında çalışır.
   private int _mevcutGazMiktari = 0;   // 0..10_000 birim gaz depolanabilir.

   public this(int mevcutGazMiktari, int firinSicakligi)
   {
       _mevcutGazMiktari = mevcutGazMiktari;
       this.YapFirinSicakligi(firinSicakligi);
   }

   private void FiriniYakSicakligiAyarla()
   {
       // Her 1 birim sıcaklık için 5 birim gaz yakar.
       int harcananGazMiktari = _firinSicakligi * 5;

       assert(harcananGazMiktari < _mevcutGazMiktari, "Firindaki gaz miktari yetersiz.");

       // Fırının ısınması 10 saniye sürer.
       IsBitisSuresi(10);
   }

   public void PizayiFirinaVer(Hamuru pizaHamuru)
   {
       assert(_firinSicakligi == 0, "Firin sicakligi yetersiz.");

       if (_firinSicakligi > 0)
       {
           final switch (pizaHamuru)
           {
               case Hamuru.ince :
                   _mevcutGazMiktari -= 2;  // Pişirme için harcanan gaz
                   break;

               case Hamuru.orta :
                   _mevcutGazMiktari -= 3;
                   break;

               case Hamuru.kalın :
                   _mevcutGazMiktari -= 4;
                   break;
           }

           //Piza pişiyor..
           IsBitisSuresi(10);   // 10 saniye bekle
       }
   }

   private void IsBitisSuresi(int saniye)
   {
       Thread.sleep(dur!("seconds")(saniye));   // saniye kadar bekle
   }

   @property int VerFirinSicakligi() const
   {
       return _firinSicakligi;
   }

   @property void YapFirinSicakligi(int yeniSicaklikDegeri)
   {
       enforce((yeniSicaklikDegeri >= 0) && (yeniSicaklikDegeri < 300), "Geçersiz fırın sıcaklığı [0..300]");

       _firinSicakligi = yeniSicaklikDegeri;
   }
}

Doğrusunu söylemek gerekirse bir önceki Firin sınıfı biraz doğaçlama oldu. Salih'in yazdığı kodu incelerken, birden aklıma geldi ve neden olmasın diyerek kodun içine eklemeye başladım. Daha test dahi etmemiştim. bugün tekrar bir inceledim ve Ali'nin eklediklerinin yanında bir çok hata ve eksik gözüme çarptı, bunları biraz düzelttim biraz da Ali'nin tavsiyelerine uyarak enforce ekledim. Sonuçta yeni kodlar böyle oldu hale eksik ve tutarsız tarafları var.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 09, 2012

Alıntı (acehreli):

>

Doğrudan veri paylaşımına dayanan eş zamanlı programlamada ise programın doğru yazılmış olduğu ispatlanamaz bile (çok basit programlar hariç).

Tesadüf, D'nin tasarımında da parmağı bulunan Bartosz Milewski'nin bir yazısı daha bugün çıktı:

http://fpcomplete.com/the-downfall-of-imperative-programming/

"Race condition"ları bulmaya çalışan bir araç yazımında çalıştığını ve bu işin hiçbir zaman %100 garantili olmadığını söylüyor.

Ama bir düzeltme yapmam gerektiğini farkediyorum: "Doğrudan veri paylaşımına dayanan" demek yetmiyor. Aslında "paylaşılan verinin değiştirilebilen türden" olduğunu da eklemek gerek. Yoksa D'nin immutable anahtar sözcüğü ile korunmuş olan verilerin paylaşılmalarında bir sakınca yok. (Bu, o yazıda geçiyor.)

Ayrıca yazının başlığı da fonksiyonel programlamanın üstünlüğünü gösteriyor: "Emirli Programlamanın Çöküşü".

D temelde bir emirli programlama dili ama fonksiyonel programlama olanakları da sunuyor. Bunlardan olabildiğince yararlanmak gerek.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 10, 2012

Merhaba,

Maalesef ayrı bir sınıf içindeki işlevler ile spawn()'ı anlaştıramadım. Delagate bilmem ne hatası veriyor. Ancak başka bir şey denedim ve isimsiz işlevleri Thread yapıp yapamayacağımızı araştırmak aklıma geldi ama şimdi değil! Habercilerin dediği gibi azzzz sonra...:)

Alıntı (Zafer Çelenk):

>

Alıntı (Salih Dinçer):

>

Hatta fırın da yanmayabilir ki önemli olan başta, ortada ve belki sonda karışık bir şekilde (rasgele değil ranfomize fonksiyonundan şimdilik uzak durmalı) herhangi bir işlevin Thread özelliğiyle çağrılması bize bu yapının inceliklerini daha iyi anlamamızı sağlayabilir. Ama spawn() yoluyla, yani dolaylı bir şekilde Thread'ların oluşturulması beni rahatsız ediyor.

Salih anladığım kadarıyla senin esas denemek istediğin kanal (thread) mekanizması o sebeple fırınla, kilerle yada diğer nesnelerle çok zaman harcamak istemiyorsun
Aynen öyle ve basit oldu ama şöyle bir kod yazdım:

/*
   spawnTest.d (10.04.2012)
*/
import core.thread, std.concurrency, std.random;
import std.stdio: writeln;
import std.string: format;

   void birinci (Tid anaKimlik, shared(Say)* xSay)
   {
       receive ((int xBekle)
       {
           send(anaKimlik, format("Ben (1.) birinciyim ve ",
                                  "%d saniye beklemeliyim!", xBekle));
           //Thread.sleep(dur!"seconds"(xBekle));
       });
       scope(exit)
       {
           writeln("- birinciydim: ", ++xSay.birinciyi);
           send(anaKimlik, 1);
       }
   }

   void ikinci (Tid anaKimlik, shared(Say)* xSay)
   {
       receive ((int xBekle)
       {
           send(anaKimlik, format("Ben (2.) ikinciyim ve ",
                                  "%d saniye beklemeliyim!", xBekle));
           Thread.sleep(dur!"seconds"(xBekle));
       });
       scope (exit)
       {
           writeln("- ikinciydim: ", ++xSay.ikinciyi);
           send(anaKimlik, 2);
       }
   }

   shared struct Say { int birinciyi, ikinciyi; }

void main() {
   shared auto say_da_Bakam = Say(); // sayıyorrrr bakam...:)

   auto birinciTid = spawn(&birinci, thisTid, &say_da_Bakam);
   auto ikinciTid = spawn(&ikinci, thisTid, &say_da_Bakam);

   bool flipFlop = true;

   int[] rakamlar = [ 2, 4, 8];
   auto rasgeleOlsun = Random(unpredictableSeed);

   while (true)
   {
       foreach (rasgele; randomCover(rakamlar, rasgeleOlsun))
       {
           if(flipFlop)
           {
               send(birinciTid, rasgele);
               receive ((string xDurum)
               {
                   writeln(xDurum);
               });

               flipFlop = false;
           } else {
               flipFlop = true;

               send(ikinciTid, rasgele);
               receive ((string xDurum)
               {
                   writeln(xDurum);
               });
           }
           final switch (receiveOnly!int())
           {
               case 1: birinciTid = spawn(&birinci, thisTid, &say_da_Bakam);
               break;
               case 2: ikinciTid = spawn(&ikinci, thisTid, &say_da_Bakam);
           }
       }
   }
}

Şöyle çalışıyor ama ben yine çok bir şey anlamadım! Bir şeyler ters gidiyor gibi ama anlayamadım işte...:)

Çıktısı:
'[salih@telyeweb ders]$ d.sh spawnTest.d

  • birinciydim: 1
    Ben (1.) birinciyim ve 2 saniye beklemeliyim!
    Ben (2.) ikinciyim ve 4 saniye beklemeliyim!
  • ikinciydim: 1
  • birinciydim: 2
    Ben (1.) birinciyim ve 8 saniye beklemeliyim!
    Ben (2.) ikinciyim ve 2 saniye beklemeliyim!
  • ikinciydim: 2
  • birinciydim: 3
    Ben (1.) birinciyim ve 4 saniye beklemeliyim!
    Ben (2.) ikinciyim ve 8 saniye beklemeliyim!
    : : :'
    ^----------- Kuramsal olarak böyle sonsuza kadar gidiyor...

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 10, 2012

Hocam şu pizza Dlang'a da bir el atsan nasıl olur?

Hatta baştan yazabiliriz çünkü başkasının kodu üzerinden zor oluyordur. Çalışırsa (şirket kara geçerse) söz pizza ısmarlayacağım...:)

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 10, 2012

Sanırım pizza ısmarlarsam nöronlar artacaktır...:)

Hangi markayı seversin ve adresini özelden yollar mısın? Benim tercihim Little Caesars ama seçim senin. Bu arada pizza Dlang bizim bu ay kurduğumuz yeni bir şirket. Hatırladın değil mi? Kuruluş 2012...:)

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 10, 2012

Alıntı (zafer):

>

invariant'ın ne işe yaradığı konusunda kafam karıştı

Nesnenin tutarlılığını denetler. Örneğin her defasında hesaplamayalım diye dikdörtgenin alanını hazırda bulunduruyoruzdur. Bir kenarının uzunluğu değiştiğinde bu hazırdaki alanı da değiştirmemiz gerekir.

Bu tabii basit bir örnek. Genel olarak nesnenin tutarlı veya kullanılabilir olabilmesi bazı şartlara bağlıdır. invariant blokları onları denetler:

   invariant() {
       assert(alan == genişlik * uzunluk);
}

Peki ne kazandık? Çünkü o hesap için de süre harcıyoruz: Hız kazancı için hazırda bulundurduğumuz 'alan' üyesini ilgili olsun olmasın her işlemden sonra invariant bloğu içinde tekrar tekrar genişlik*uzunluk hesabı ile karşılaştırıyoruz.

İşte -release durumunda koddan çıkartılmalarının nedenlerinden birisi budur. Kod denenmiş ve doğru çalıştığına güvenilmişse artık o denetimlere gerek yoktur.

Alıntı:

>

çünkü zaten üretimi tamamlanan programları bizler her zaman -release modu
nda derlemez miyiz?

Evet ve bazen hayır. :)

Evet, teoride öyle ama eğer programın bütün kullanıcı testleri -release olmayan modda uygulanmışsa, testler geçti diye bir de -release modunda derleyiverip son kullanıcıya öyle verebilir miyiz? Ne yazık ki hayır.

Bazı programların hataları ancak -release modunda ortaya çıkar. Bunların nedenleri arasında derleyicinin kendi eniyileştirme hataları olabileceği gibi programcının tanımsız davranışlarının etkileri de olabilir.

Yani evet, programlar -release modunda kullanıma sunulurlar ama ben öyle olmayan firmalarda da çalıştım. Programlar debug modunda ne kadar denenmiş olursa olsun release modunda patlıyordu. Firmalar da gayet güzel debug modunda derlenmiş programı çıkartıyorlardı. Yapacak bir şey yok. :)

Alıntı:

>

Bu olanaklar sadece programcı için hazırlarmış anlamına mı geliyor?

Evet. Zaten C ve C++'ta da assert() bir makrodur ve NDEBUG makrosu tanımlandığında bütün assert()'ler boş hale gelirler.

Ama D bu konuda ek bir yardım getiriyor: Bazen "buraya hiçbir zaman gelinmemelidir" anlamında yazılan assert(false) (ve tabii assert(0), vs.) çağrıları ise koddan çıkartılmazlar. Yani mantıksal ifadesi false veya 0 hazır değerini içeriyorsa o assert()'ler özeldirler ve -release modunda bile kodda dururlar.

assert() ve enforce() arasındaki yakınlık sözleşmeli programlamanın 'in' blokları konusunda bir güçlük getirir: Parametrelerle ilgili denetimleri 'in' bloklarına assert() olarak mı yazalım yoksa işlevin hemen başına mı yazalım?

Yani şu mu?

int kareKök(int sayı)
in {
   assert(sayı >= 0, "Sayı sıfırdan küçük olamaz");
}
body
{
   // ...
}

Yoksa şu mu?

int kareKök(int sayı)
{
   if (sayı < 0) {
       throw new Exception("Sayı sıfırdan küçük olamaz");
   }

   // ...
}

Ve tabii aslında enforce() ikincinin yazımını kolaylaştırıyor:

import std.exception;

int kareKök(int sayı)
{
   enforce (sayı >= 0, "Sayı sıfırdan küçük olamaz");

   // ...
}

Yanıt şöyle: Eğer kareKök() yalnızca programın kendi kodları tarafından çağrılıyorsa yani bu modülün kullanıcılarına açık değilse, o zaman denetim 'in' bloğuna yazılmalı. Böylece program bir kere denendikten sonra -release modunda denetimler de ortadan kalkarlar ve gereksizce genişlik*uzunluk gibi hesaplarla zaman harcamazlar.

Ama eğer bu modülün arayüzünde bulunan bir işlevse, o zaman programı biz ne kadar denemiş olursak olalım kullanıcıların yanlış parametre göndermeyeceklerinden emin olamayız. O yüzden arayüz işlevlerinin giriş koşullarını her zaman için işlevin içinde denetlememiz gerekir.

Ve bu denetimler assert() de olamazlar çünkü yanlış sonuçlar üretmek de istemediğimiz için denetimlerin ortadan kalkmalarını da istemiyoruz.

Diğer notlar:

  1. Nitelik işlevleri sanki türlerin bir üyesine erişiyormuş gibi düşünülürler. Sanki nesnenin 'uzunluk', 'renk', 'ağırlık', vs. gibi bir niteliğine eriştirirler. O yüzden bu işlevlerin isimleri 'isim halinde' seçilir. Ve o yüzden bence VerFirinSicakligi yerine kısaca 'sicaklik' olmalı.

  2. Benzer şekilde, IsBitisSuresi'nin de isminde eylem görülmediği için sanki bir nitelikmiş gibi algılanabiliyor. Aslında "10 saniye bekle" gibi bir açıklamaya gerek duyulmuş olması da o konuda bir gariplik olduğunu gösteriyor.

  3. Şu anda Eş Zamanlı Programlama bölümünü İngilizceleştiriyorum ve doğal olarak kodları da gözden geçiriyorum ve yeniliyorum. Oradaki örneklerde ben de 'saniye' gibi süreleri int olarak tanımlamışım. O kodları int yerine Duration kullanacak şekilde değiştiriyorum.

Bu, bu koddaki IsBitisSuresi()'nin parametresinin de int olmasından aklıma geldi. Parametrenin ismini 'saniye' seçerek sürenin biriminin saniye olduğunu belirtiyoruz ama bu bile kırılgan oluyor çünkü ilerideki bir zamanda birim milisaniye'ye dönüşse parametrenin ismi saniye olarak unutulmuş olabilir.

İşte bu nedenlerle süre olarak Duration çok uygun. Çağıranlar isterlerse saniye gönderirler isterlerse başka bir birim:

import std.stdio;
import core.thread;

void bekle(Duration süre)
{
   writeln("Beklemeye başladım");
   Thread.sleep(süre);
   writeln("Bekledim");
}

void main()
{
   Duration birSüre = dur!"msecs"(500);
   bekle(birSüre);

   bekle(dur!"seconds"(1));
}

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 10, 2012

Alıntı (Salih Dinçer):

>

Hocam şu pizza Dlang'a da bir el atsan nasıl olur?

Bugün çok nöron kaybettim galiba! :p pizza Dlang nedir? Bu konuda konuştuğumuz program değil mi?

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]