Forum: Ders Arası RSS
TypeTuple "parametre listesi" kavramıymış
acehreli (Moderatör) #1
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: TypeTuple "parametre listesi" kavramıymış
std.typetuple modülünün olanağı olan TypeTuple şuradaki bölümün sonunda çok kısa olarak geçmişti:

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

(O bölüm bu mesajdan bir kaç hafta sonra iki bölüme ayrılacak.)

Öncelikle oradaki çokuzlu (tuple) kavramını anlamak gerekiyor. Ben TypeTuple'ın kullanım örneklerini biliyordum ve gerektiğinde istediğim sonucu alabiliyordum. TypeTuple'ın tam olarak ne olduğunu çok yeni anladım.

TypeTuple, parametre listesi denen D olanağını oluşturmaya ve yönetmeye yarıyor. Parametre listesi işlevlerde ve şablonlarda hep karşımıza çıkar:
void işlev(int i, string s, double d)
{
    // ...
}
 
struct Yapı(string s, double d, float f)
{
    // ...
}
Yukarıda bir işlev ve bir yapı şablonu var. Normalde her ikisini de açıkça üç parametre değeri ile kullanabiliriz.

TypeTuple, parametre listesi kavramını programcıya sunuyor:
    alias parametreler = TypeTuple!(42, "merhaba", 1.5);
parametreler artık (42, "merhaba", 1.5) gibi bir parametre listesini temsil ediyor. Örneğin, işlevi yalnızca parametreler ile çağırabiliriz:
    işlev(parametreler);    // aslında üç parametre gönderiliyor 
TypeTuple dizi işleçleriyle kullanılabiliyor: parmetreler[ i ] yasal... Başka örnek:
    auto nesne = Yapı!(parametreler[1..$], 2.5)();
Bir anlamda, TypeTuple her yerleştiği yere parametre listesi olarak açılmış oluyor. Hepsi aynı türden olsa dizi elemanları için de kullanılabiliyor:
    auto diziElemanları = TypeTuple!(1, 2, 3, 4);
    auto dizi = [ diziElemanları ];
Yukarıdaki gibi yerel parametre listesi oluşturmak pek yaygın bir ihtiyaç değil. TypeTuple'lar en çok belirsiz sayıda parametreyle (variadic function, veya variadic template) ilgilenirken işe yarıyor:
long topla(T...)(T parametreler)
{
    // T, bir TypeTuple'dur
}
Yukarıdaki işlev şablonu belirsiz sayıda parametreyle çağrılabilir:
    topla(1, 2, 3)
Tabii işin güzeli, kendisi bir şablon olduğundan bütün parametrelerinin aynı türden değerler olmaları gerekmiyor. Garip bir örnek olarak yalnızca int'leri toplayan bir işleve bakalım:
long intleriTopla(T...)(T parametreler)
{
    long sonuç = 0;
 
    foreach (parametre; parametreler) {
        static if (is (typeof(parametre) == int)) {
            sonuç += parametre;
        }
    }
 
    return sonuç;
}
(Not: Aşağıdaki bütün programdaki bir açıklamada göreceğiniz gibi, yukarıdaki foreach derleme zamanında kod açılımıdır; çalışma zamanında döngü değildir.)

Aşağıdaki örnek yalnızca int olan parametreleri topluyor:
    assert(intleriTopla(10, "merhaba", 2.5, 20) == 30);
Aşağıdaki örnek işlev writefln gibi işliyor ama düzen bilgisini her değerden önce alıyor (kodu aşağıdaki programda):
    benimWritefln("(%s)", 1, "{%s}", 2, " üçüncü değer: %s", 3);
Yani, yukarıdaki çağrı aşağıdakinin eşdeğeri:
    writefln("(%s){%s} üçüncü değer: %s", 1, 2, 3);
Dediğim gibi, saçma bir örnek... :)

Bütün program aşağıda... TypeTuple da bütünüyle derleme zamanı olanağı olduğu için foreach'ler aslında kod olarak açılırlar ve static if gibi derleme zamanı olanaklarını kullanmak gerekiyor.
import std.stdio;
import std.typetuple;
 
void işlev(int i, string s, double d)
{
    writefln("işlev çağrıldı: %s %s %s", i, s, d);
}
 
struct Yapı(string s, double d, float f)
{
    void üyeİşlev()
    {
        writefln("Yapının şablon parametreleri: %s %s %s", s, d, f);
    }
}
 
long topla(T...)(T parametreler)
{
    // T, bir TypeTuple'dur
 
    long sonuç = 0;
 
    foreach (değer; parametreler) {
        sonuç += değer;
    }
 
    /*
     * UYARI:
     *
     * Yukarıdaki foreach çalışma zamanında işletilen bir döngü değildir;
     * foreach'in içindeki işlemlerin derleme zamanında kod içine gereken
     * sayıda açılmasından üretilen bir kod bloğudur. Örneğin, 3 parametre ile
     * çağrıldığında yukarıdaki döngü şunun eşdeğeridir:
     *
     *    {
     *        sonuç += parametreler[0];
     *    }
     *    {
     *        sonuç += parametreler[1];
     *    }
     *    {
     *        sonuç += parametreler[2];
     *    }
     */
 
    return sonuç;
}
 
long intleriTopla(T...)(T parametreler)
{
    long sonuç = 0;
 
    foreach (parametre; parametreler) {
        static if (is (typeof(parametre) == int)) {
            sonuç += parametre;
        }
    }
 
    return sonuç;
}
 
/*
 * Parametreler çift sayıda olmalıdır: Önce düzen dizgisi, sonra değer.
 */
void benimWritefln(T...)(T parametreler)
    if ((parametreler.length % 2) == 0)
{
    string düzen;
 
    foreach (i, parametre; parametreler) {
        static if ((i % 2) == 0) {
            // Bu, düzen belirteci. Önce string olduğunu denetleyelim
            static assert(is (typeof(parametre) == string));
 
            düzen = parametre;
 
        } else {
            // Bu, yazdırılacak olan değer. Yazdıralım...
            writef(düzen, parametre);
        }
    }
 
    // Sondaki satır sonu
    writeln();
}
 
void main()
{
    alias parametreler = TypeTuple!(42, "merhaba", 1.5);
    işlev(parametreler);
 
    auto nesne = Yapı!(parametreler[1..$], 2.5)();
    nesne.üyeİşlev();
 
    auto diziElemanları = TypeTuple!(1, 2, 3, 4);
    auto dizi = [ diziElemanları ];
    writefln("dizi: %s", dizi);
 
    writefln("toplam: %s", topla(1, 2, 3));
 
    assert(intleriTopla(10, "merhaba", 2.5, 20) == 30);
    writefln("int'lerin toplamı: %s", intleriTopla(10, "merhaba", 2.5, 20));
 
    benimWritefln("(%s)", 1, "{%s}", 2, " üçüncü değer: %s", 3);
    /* Üsttekinin eşdeğeri:
     *
     *     writefln("(%s){%s} üçüncü değer: %s", 1, 2, 3);
     */
}
Ali
Bu mesaj acehreli tarafından değiştirildi; zaman: 2013-08-15, 11:09.
Avatar
Salih Dinçer #2
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Bunlar çok güzel...

Durağan olanaklar olsa da programcıya, ayrıntılarla boğuşma işlemini derleyiciye bırakıp daha çok vakit kazandırıyor. Tek korkum, diğer taraftan dolaylı olarak vakit kaybettirmesi; derleme zamanının artması...

Belki basit örneklerde anlaşılması zor olabilir ama bütün kalıp (template) olanaklarını ve doğal olarak bunların yeteneklerinden faydalanabilmek için durağan (static) nesneleri kullandığımızda geliştirme zamanı uzayabilir. Malumunuz çok küçük bir değişiklikte bile yazılımı derleyip sonucunu görmek istiyoruz. Hatta düzeltmeleri yaparken birden değil adım adım yaparak yazılım kararlılığını bozmamaya özen gösteriyor. İşte derleyiciye bu kadar çok yüklenirsek büyük bir projede ne olur bilemem...:)
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Avatar
zekeriyadurmus #3
Kullanıcı başlığı: Talha Zekeriya Durmuş
Üye Eki 2012 tarihinden beri · 701 mesaj · Konum: Samsun/Türkiye
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Hocam http://ddili.org/forum/post/8379 bu adreste tartışmış olduğumuz olayı TypeTuple ile yapabiliriz o halde?

Zekeriya
Bilgi meraktan gelir...
acehreli (Moderatör) #4
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
TypeTuple şimdilik yalnızca derleme zamanındaki değerlerle (ve türlerle) kullanılabiliyor.

Şablonlarla kullanılabilmesi için bunun şart olduğu açık çünkü şablonlar kod üretimi olanakları olduklarından derleme zamanında derlenirler ve konu kapanır. (Diğer konudaki format() bir işlev şablonudur.)

C gibi variadic işlev parametrelerinde ise boş bir parametre listesinden başlayıp onu doldurmak ve bir variadic işleve göndermek mümkün gibi geliyor ama nasıl yapıldığını bilmiyorum.

Ali
Avatar
huseyin #5
Üye Haz 2012 tarihinden beri · 363 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Gerçekten güzel bir özellikmiş. D ' nin gelişmesi ne kadar devam edecek? Bilginiz var mı @acehreli hocam?
Huseyin
acehreli (Moderatör) #6
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Kimse dilin aslının değişmesinden yana değil ama tek tük düzeltmeler ve eklemeler gerekebiliyor. Şimdilik ufukta D3 diye bir şey yok.

Ali
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Forum: Ders Arası RSS
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-19, 06:03:42 (UTC -08:00)