Jump to page: 1 25  
Page
Thread overview
October 28, 2012

Arkadaşlar d dilinde array içerisinde array nasıl kullanabiliriz?

Mesela pythonda
dizi =[2]
dizi.append([1])
dizi[1].append(1,2)
dizi.append("yazı")

şeklinde yazdığımızda sonuç olarak [2, [1,1,2], "yazı"] gibi bir sonuç dönüyor.
Yani dizi sonsuz boyutlu ve her tür veriyi içerisinde barındırabiliyor.

Bunu d de nasıl yapabiliriz?

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

October 28, 2012

Aramıza hoş geldin Zekeriya...

Bu konuda Ali hocam daha yetkin cevap verecektir ama D'de bu olayın karşılığı çokuzlu (Tuples) kullanmak olabilir. Örneğin:

   import std.stdio;

   /* Önce aşağıdaki gibi bir şablon kuruyoruz...
    * Bu sayede farklı türde tüm verileri bir araya topluyoruz!
    */
   template Çokuzlu(E...)
   {
       alias E Çokuzlu;
   }

void main()
{
   /* Kullanmak için ise gayet basit şekilde
    * Tüm verileri şablon için tanımlıyoruz...
    */
   alias Çokuzlu!(2, [1,1,2], "yazı") dizi;

   foreach(ç; dizi) ç.writeln;/* ya da aynı çıktıyı veren:
//  ^--- (toggle-on/off) alt satırı açmak için // kullan
   dizi[0].writeln; // 2 yazar
   dizi[1].writeln; // [1,1,2] yazar
   dizi[2].writeln; // yazı yazar

//*/
}

Başarılar...

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

October 28, 2012

Öncelikle verdiğiniz cevaplar için teşekkür ederim.

Derleme zamanında bu dizi tamamen boş olacak çalışma zamanında buraya sürekli dizi, yazı vs eklenecek. Tabi bu yazılar dizinin içerisine de yazılacak hatta dizinin içindeki dizinin içine kadar yazılabilecek.

Sadece çalışma zamanı esnasında içerisine dizi, string ve pythondaki gibi kitaplık (aynısı d de var) eklensin yeter benim için.

kitaplık derken:
string b[string];
b["key"]="val";

Teşekkür ederim.

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

October 28, 2012

Sanırım Python'da kitaplık, D'de eşleme tablosu (associative arrays)...

Bence bir bağlı liste yapılarak farklı veri türleri bir diziymiş gibi bağlanabilir. Dizideki elemanlar aslında işaretçi olur...

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

October 28, 2012

Hoşgeldin zekeriyadurmus! :)

Salih'in gösterdiği olur ama ancak bir araya getirilen parçalar baştan (yani derleme zamanında) biliniyorsa olur.

D, strongly statically typed bir dildir. Her değişkenin türü derleme zamanında belirlenmiş olmak zorundadır. Python örneğindeki gibi bir dizinin türünü D'de söyleyemeyiz bile: "int dizisi" olmaz, "int'lerden ve int dizilerinden oluşan dizi" olmaz. İkincisi olsa bile bu sefer Python'da onun içine bambaşka türler bile eklenebiliyor (galiba).

Ek olarak, bir kütüphane olanağı olarak Variant var. O türün arkasına istediğimiz başka türü gizleyebiliriz ve böylece "Variant dizisi" oluşturabiliriz.

Bunun gibi başka yöntemler de var. Probleme göre düşünmek gerek.

Ama sorunun kısa yanıtı: Hayır, D'de yapılamaz. :)

Ali

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

October 29, 2012

Pythonı kullanarak kendi interpreterımı yazdım. Ama gel gör ki python da c ile yazılmış bir interpreter olmasından dolayı oldukça yavaş haliyle bana aşırı hızlı bir dil lazımdı, araştırma ve testler sonucunda d dilinde karar kılındı.
Txt dosyasından okuduğum kodları parse ettikten sonra bunların bir şemasın çıkarmam gerekiyordu. Ama bu şemayı bir türlü oluşturamadım çünkü pythondaki gibi sonsuz boyutlu birşey yoktu ayrıca yazacağımız dilin python gibi bir array yapısına sahip olacağını düşünürsek eğer d de çok basit bir sonsuz boyutlu array oluşturamamak projenin önüne koca bir engel koydu.
İstediğim şey sadece
[{"a": "b", "x": {"c": ["1","2","3"]}}, {"t": "1", 'y': "2"}]
gibi içerisinde associative array, array ve string barındırabilen sonsuza dek genişleyebilen bir yapı.

Teşekkür ederim.

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

October 28, 2012

Alıntı (zekeriyadurmus):

>

çalışma zamanı esnasında içerisine dizi, string ve pythondaki gibi kitaplık (aynısı d de var) eklensin

Tam olarak nasıl bir problem çözmeye çalışıyoruz? Aynı topluluğun elemanlarının o kadar farklı olmaları D'nin mantığına uymuyor. Yine de yapılabilir ama Python'daki kadar kolay olmaz.

Elemanların aralarında bir benzerlik olsa, örneğin hepsine Veri bile diyebilsek, bir Veri arayüzü kullanılabilir. Tabii o arayüzün üye işlevinin ne olacaklarını tahmin edemiyorum.

Ali

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

October 28, 2012

Bir ekleme yapmam gerektiğini düşündüm. Öncelikle, sözüm meclisten dışarı, çünkü bu gerçekten evrensel bir konu.

Yeni bir dile baktığımızda o dilin belirli bir olanağı sunmadığını farkederek şaşırabiliyoruz. Hemen aklıma gelen bir örnek: D'ciler şablon gibi türden bağımsız programlama (generic programming) olanakları bulunmayan başka dillere şaşırırlar. Geçenlerde Go'nun başındakilerden birisinin bir blog yazısını okumuştum. O kişi de Go için benzer şeyler söylendiğini yazıyordu ve sonunda da "Go'ye eksik bulmadan önce aynı problemlerin Go'da nasıl çözüldüklerine bir bakın" diyordu. Haklı.

Burada da Python'ın olanağı bana hem çok esnek ve kolay, hem de çok çılgınca geliyor. :) Diğer taraftan bakınca da D yetersizmiş gibi görünüyor. En iyisi, daha önce de söylediğim gibi, problemi tam olarak anlarsak D'de ne tür çözümler bulunduğuna bakabiliriz.

Ali

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

October 29, 2012

Bu durumda interface{ } önderliğinde türler arası bir köprü oluşturabiliriz:

interface Köprü { }

class Değer(T) : Köprü {
 T s;

 this(T s) { this.s = s; }

 override
 string toString() const {
   return s.format;
 }
}

class Dizi(T) : Köprü {
 T[] d;

 this(T[] d) { this.d = d; }

 override
 string toString() const {
   return d.format;
 }
}

import std.stdio, std.string;

void main() {
 Köprü[] Topluluk;

         Topluluk ~= new Değer!string("Dünya nüfusu:");
         Topluluk ~= new Değer!short(7);
         Topluluk ~= new Değer!string("Milyar ve içinde yaşayanlar: ");
         Topluluk ~= new Dizi!string(["Ali Çehreli",
                                      "Salih Dinçer",
                                      "Zekeriya Durmuş" ]);
         Topluluk.writeln;
}

Çıktısı:
'[Dünya nüfusu:, 7, Milyar ve içinde yaşayanlar: , [Ali Çehreli,Salih Dinçer,Zekeriya Durmuş]]'

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

October 29, 2012

Alıntı (zekeriyadurmus):

>

Txt dosyasından okuduğum kodları parse ettikten sonra bunların bir şemasın çıkarmam gerekiyordu.

O kadarıyla zor bir iş gibi görünmüyor.

Alıntı:

>

Ama bu şemayı bir türlü oluşturamadım çünkü pythondaki gibi sonsuz boyutlu birşey yoktu

Oysa D'nin dizileri ve eşleme tabloları (associative array) da sonsuza kadar büyüyebilirler. (?) Ayrıca std.container gibi modüllerde bağlı listeler de var. (Ama std.container'ın modern D'ye daha uygun bir modülle değiştirilmesi de bekleniyor.)

Ama kod örneklerinden anladığıma göre burada aslında bir ağaç veri yapısı da gerekiyor olabilir.

Python'dan farklı olan şu: Herhangi bir topluluğun elemanlarının hep aynı türden olmaları gerekir. Bu, verinin işlendiği noktada önem kazanır. Python bize türler konusunda derleme zamanında hiçbir güvence getirmez. Örneğin, dizide bir int bulunsa bile kod o int'i bir dizi gibi kullanmaya çalışabilir. Bu hata ancak çalışma zamanında ve belki de program uzun bir süre çalıştıktan sonra anlaşılabilir. Hatta, bütün testlerden geçmiş bile olsa program bir kaç ay sonra tek kullanıcı için çalışırken göçebilir.

D gibi strongly statically typed dillerde verinin aynı türden olmasının gerekmesini bir kısıtlama olarak görmemek gerekir. Genel olarak "aynı türden" oldukları halde özel olarak bakıldığında "farklı türden" olan nesneler de bir araya gelebilirler.

D'de bu amacı karşılayan çeşitli olanaklar var. Bunlara bakmadan önce verinin nasıl işleneceğine bakmak gerekir. Metin dosyasından okunan bu verilere genel olarak bir isim verebiliyor muyuz? Örneğin hepsi de Komut mu? Ve bu komutların hepsinin de sağlaması gereken bir işlem var mı? O zaman NYP uygulanabilir:

interface Komut
{
   void işlet();
}

class KopyalamaKomutu : Komut
{
   string kaynak;
   string hedef;

   // ...

   void işlet()
   {
       // ... kopyalama işlemi ...
   }
}

// Sonsuza kadar büyüyebilen bir Komut dizisi
   Komut[] komutlar;
   komutlar ~= new KopyalamaKomutu("foo.d", "bar.d");
   komutlar ~= new SilmeKomutu("zar.d");

Tahmin ettiğim gibi ağaç gibi dallanabiliyorsa, yani her komutun alt komutları olabiliyorsa o zaman bazı düğümler yalnızca bir Komut[] gibi davranırlar ve böylece ağaç yapısı tamamlanmış olur.

Düşünürsek, böyle bir ağaç yapısında iki tür Komut vardır: ÇokluKomut, TekliKomut. Uyarı: Aşağıdaki program gereğinden karmaşık görünebilir. Daha sonra basitleşecek:

import std.stdio;

// Bu yalnızca bir arayüz. Bu sıradüzenin kullanıcıları en azından işlet()
// işlevini bekleyecekler.
interface Komut
{
public:

   void işlet();
}

class TekliKomut : Komut
{
public:

   /* Tekli komut işletmek her komutun özel işleticisini çağırmak kadar
    * basittir.
    *
    * Not: Aslında buna gerek yoktur çünkü alt sınıflar işlet_özel()
    * işlevinin tanımını vermek yerine doğrudan işlet() işlevinin tanımını da
    * verebilirler.
    *
    * Bu yöntem ise bize bütün tekli komutların işletilmesi sırasında araya
    * girebileceğimiz bir olanak sağlar. Örneğin her tekli komut için
    * işletilecek olan bir adımı burada gerçekleştirebiliriz.
    *
    * Bu yönteme 'template method design pattern' denir (ama şablonlarla
    * ilgisi yoktur.) Başka bir adı da "non virtual interface"tir.
    */
   void işlet()
   {
       işlet_özel();
   }

protected:

   // İşte alt sınıflar bunu tanımlamak zorundadırlar
   abstract void işlet_özel();
}

class ÇokluKomut : Komut
{
private:

   // Kendisi bir Komut olduğu halde birden fazla komuttan oluşuyor
   Komut[] komutlar;

public:

   // Kurucu bir veya daha fazla komutla başlayabilir
   this(Komut[] komutlar...)
   {
       /* Not: Burada daha normal olarak şöyle yazabilmek isterdim:
        *
        *     this.komutlar = komutlar;
        *
        * Öyle yapınca program parçalama hatası veriyor çünkü "..." ile
        * işaretlenmiş olan parametre gereğinden erken sonlandırılıyor. Bence
        * öyle olmamalı. Araştıracağım ve gerekirse bir dmd hatası açacağım.
        *
        * Ama ~= işleci çalışıyor:
        */
       this.komutlar ~= komutlar;
   }

   // Sonradan da komut eklenebilir
   void ekle(Komut komut)
   {
       komutlar ~= komut;
   }

   // Çoklu komutun işletilmesi alt komutlarının sırayla işletilmeleridir
   void işlet()
   {
       foreach (komut; komutlar) {
           komut.işlet();
       }
   }
}

// Yukarıdaki temel oluşturulduktan sonra farklı komutların tanımlarına
// geçebiliriz.

// Kopyalama komutu tekli bir komut olsun
class Kopyala : TekliKomut
{
private:

   string kaynak;
   string hedef;

public:

   this(string kaynak, string hedef)
   {
       this.kaynak = kaynak;
       this.hedef = hedef;
   }

protected:

   override void işlet_özel()
   {
       writefln("%s dosyasını %s olarak kopyalıyorum", kaynak, hedef);
   }
}

// Silme komutu da tekli bir komut olsun
class Sil : TekliKomut
{
private:

   string dosya;

public:

   this(string dosya)
   {
       this.dosya = dosya;
   }

protected:

   override void işlet_özel()
   {
       writefln("%s dosyasını siliyorum", dosya);
   }
}

// Taşımanın başka yolları olsa da, örnek olsun diye taşıma komutunu diğer
// ikisinin bileşimi olarak gerçekleştirelim. Dolayısıyla bu çoklu bir komut
// olacak
class Taşı : ÇokluKomut
{
public:

   this(string kaynak, string hedef)
   {
       // Bunun tek yaptığı, üst sınıfını memnun etmek olacak. O işi de bir
       // kopyalama bir de silme komutu vererek gerçekleştiriyoruz:
       super(new Kopyala(kaynak, hedef), new Sil(kaynak));
   }

   // Başka işlem gerekmiyor
}

void main()
{
   // Artık sonsuz karmaşıklıkta bir komut ağacı oluşturabiliriz:
   Komut[] komutlar;

   // Aşağıdaki işlemleri örneğin çalışma zamanında taradığımız bir metin
   // dosyasından öğrenebiliriz:
   komutlar ~= new Kopyala("bundan_kopyala.txt", "buna_kopyala.txt");
   komutlar ~= new Sil("zararli_dosya.txt");
   komutlar ~= new Taşı("yanlis_isim.txt", "dogru_isim.txt");

   foreach (komut; komutlar) {
       komut.işlet();
   }

   // Bu kadar çeşit komutla bile istediğimiz kadar derine
   // dallanabileceğimizi görelim:
   auto derinKomut =
       new ÇokluKomut(new Sil("duzey0_dosya0"),
                      new ÇokluKomut(new Sil("duzey1_dosya0"),
                                     new ÇokluKomut(new Sil("duzey2_dosya0"),
                                                    new Sil("duzey2_dosya1"))));
   derinKomut.işlet();
}

Eğer amaç yukarıdaki Komut gibi temel bir tür değilse veya böyle bir temel zorlama gelecekse o zaman std.variant kullanılabilir. Uyarı: Tabii kimse böyle kod yazmaz, yine dosyadan okunan verinin bir Variant[] dizisine yerleştirildiğini düşünebiliriz:

import std.variant;

void main()
{
   Variant[] veriler = [
       Variant([ Variant(["a" : Variant("b"),
                          "x" : Variant([ "c": ["1","2","3"] ] )]),

                 Variant([ Variant("t") : "1", Variant('y') : "2" ] ) ] )];
}

Alıntı:

>

d de çok basit bir sonsuz boyutlu array oluşturamamak projenin önüne koca bir engel koydu.

Bunun başka yolları da var. Ama o zaman güvenliği ve hızı gözardı etmiş oluruz (her ikisi de D'nin temel amaçlarındandır).

Alıntı:

>

İstediğim şey sadece
[{"a": "b", "x": {"c": ["1","2","3"]}}, {"t": "1", 'y': "2"}]
gibi içerisinde associative array, array ve string barındırabilen sonsuza dek genişleyebilen bir yapı.

O yapıyı nasıl işleyeceksin? Elemanların teker teker hangi türden olduklarına nasıl karar verebiliriz:

struct EsnekYapı
{
   // ...
}

void işle(EsnekYapı[] veri)
{
   // Burada ne yapabiliriz? veri[0]'ın asıl türü nedir?
}

void main()
{
   EsnekYapı[] veri;
}

Sonsuza kadar büyüyebilen veri yapıları her dilde yapılabilir. Örneğin Python yorumlayıcısının bile C'de yapılabildiğini biliyoruz. C'den daha üstün olan D'de daha da kolay yapılır.

Bizim on sene önce yazılmış bir C kütüphanemiz var. Örneğin orada şöyle bir birlik kullanılıyor. Bu zaten Variant'ın da perde arkasında uyguladığı yöntemdir. (D kodu olarak gösteriyorum):

import std.stdio;

enum Tür { intT, doubleT }

struct Veri
{
   Tür tür;

   union
   {
       int i;
       double d;
       // ... desteklenen diğer türler ...
   }
}

void işle(Veri veri)
{
   final switch (veri.tür) with (Tür) {
   case intT:
       writeln("int işliyorum: ", veri.i);
       break;

   case doubleT:
       writeln("double işliyorum", veri.d);
       break;
   }
}

void main()
{}

Ek olarak, D'nin derleme zamanı olanakları çok üstün olduğundan, tam da o veri dosyasını taramayı bilen bir tür derleme zamanında bile oluşturulabilir. O zaman bir DSL (domain specific language) uygulamış olunur.

Sonuçta çözüm çok. :)

Ali

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

« First   ‹ Prev
1 2 3 4 5