Thread overview
Yeni önerilen 'any' işlevi
January 10, 2011

C'de de yaşadığım önemsiz bir sıkıntı vardır: bir değişkenin bazı değerlerden birisi olup olmadığını denetlemek için aynı karşılaştırma || ile art arda tekrarlanır:

void foo(dstring gün)
{
   if ((gün == "Cumartesi") ||
       (gün == "Pazar")) {
       writeln("Hafta sonu");

   } else {
       writeln("İş günü");
   }
}

(Not: D'de dizgiler switch deyimlerinde de kullanılabiliyor; C'deki sıkıntıyı göstersin diye bu örneğe takılıyorum.)

Oradaki 'gün ==' karşılaştırmaları yerine hep şöyle yazabilmek istemişimdir:

   if (gün == ("Cumartesi" || "Pazar")) {  // <-- DERLEME HATASI

Öyle yazınca "gün, Cumartesi veya Pazar mı" demek isterim ama || bir mantıksal ifade olduğu için ve dizgiler mantıksal ifadelerde kullanılamadıkları için derlenemez.

Daha kötüsü, bazı yeni başlayanlar gerçekten öyle yazdıklarında ama tesadüfen mantıksal ifadeye dönüşebilen türler kullandıklarında, kod derlenir ve yanlış çalışır. Örneğin gün ismi yerine gün numarası kullanmış olsak:

void foo(int gün)
{
   if (gün == (6 || 7)) {
       writeln("Hafta sonu");

Sıfırdan farklı değerler mantıksal ifadelerde 'true' değerinde oldukları için sağdaki ifade (true || true) olur, sonucu true'dur ve o da 'gün' gibi bir int ile karşılaştırıldığında 1 değerini alır. Sonuçta da yalnızca gün numarası 1 olduğunda, yani Pazartesi olduğunda eşitlik doğru çıkar ve sonuç yanlıştır: Pazartesi için "Hafta sonu" yazılır, diğer günler için "İş günü"!

Yine konuyu fazla uzattım. :) Asıl söylemek istediğim; bunu sağlayan bir işlev, Phobos'a eklenmek üzere... Adını önce 'either' olarak önerdiler ama galiba 'any' veya 'isAny' olacak. Gerçekleştirmesinde fazla konuşmadığımız şablon çokuzlu parametreleri (template tuple parameters) geçiyor ama çok kolay kullanılıyor (İngilizce forumdan aktarıyorum):

import std.stdio;
import std.typecons;

struct Any(Ts...)
{
   Tuple!Ts data_;
   bool opEquals(E)(E e)
   {
       foreach (i, T; Ts)
       {
           if (data_[i] == e) return true;
       }
       return false;
   }
}

auto any(Ts...)(Ts args)
{
   return Any!Ts(tuple(args));
}

void foo(int gün)
{
   if (gün == any(6, 7)) {
       writeln("Hafta sonu");

   } else {
       writeln("İş günü");
   }
}

void main()
{
   foo(7);
}

Şablon çokuzlu parametrelerine şurada "Çokuzlu parametreleri" başlığı altında değinmiştim:

http://ddili.org/ders/d/sablonlar_ayrintili.html

Ali

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

January 22, 2011

Alıntı:

>

C'de de yaşadığım önemsiz bir sıkıntı vardır: bir değişkenin bazı değerlerden birisi olup olmadığını denetlemek için aynı karşılaştırma || ile art arda tekrarlanır:

Ya && işlecini kullanmak istersek.
Örneğin şu biçimde bir kod parçacığı var:

  char satır_kontrol()
   {
       for(int a=1;a<4;a++){
           writeln(a);
           if((tablo[a][0]==tablo[a][1])&&(tablo[a][1]==tablo[a][2])){
               return tablo[a][a];
           }
       }
       return 'y';
   }

   char sütun_kontrol()
   {
       for(int a=1;a<4;a++){
           if((tablo[0][a]==tablo[1][a])&&(tablo[1][a]==tablo[2][a])){
               return tablo[a][a];
           }
       }
       return 'y';
   }

   char çapraz_kontrol()
   {
       if((tablo[0][0]==tablo[1][1])&&(tablo[1][1]==tablo[2][2])){
               return tablo[1][1];
           }else if((tablo[0][2]==tablo[1][1])&&(tablo[1][1]==tablo[2][0])){
               return tablo[0][2];
           }

       return 'y';
   }

any işlevi ve, veya, ya da gibi işleçlerin hepsi ile çalışacak biçimde yazılırsa bence daha güzel olur. Sizce?

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

January 22, 2011

Haklısın. Ama && konusu biraz daha karışık. || durumunda hep tek değişkeni karşılaştırıyoruz. && durumunda ise aynı değişkeni karşılaştıramayız; yani değişken 1'e eşit olsun, 10'a da eşit olsun, vs. gibi olmaz. || işlemi bu konuda özel galiba.

O yüzden senin örneğinde de oldukça özel bir durum var: "bundan sonraki üçü aynıysa" gibi.

|| durumunda hep == işleci kullanılıyor. Ama eğer bir koşul dizisi oluşturur ve "bu değişken bütün koşullara uyar mı" veya "koşulların yalnızca birisine uyar mı" dersek olur.

find'ın aldığı tek koşul yerine bir çok koşul koyarız belki:

   if (hepsineUyar_mı(değişken,
                      (a){ a % 3 == 0 },
                      (a){ a >= 20 },
                      (a){ a < 100 })) {
       // ...
   }

Yazım hatası olabilir; bakmadan yazdım. :)

Ali

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