Thread overview
GBS-5: Bir işlev içindeki yapı(sihir)
Jan 30, 2022
Salih Dincer
Jan 30, 2022
Salih Dincer
Jan 30, 2022
Ali Çehreli
Jan 30, 2022
Ali Çehreli
Jan 30, 2022
Salih Dincer
January 30, 2022

Hokusss, pokus!

Evet, şimdi denediğim şey bana sihir gibi geliyor ki sanırım amatör bir programcı olduğumdandır. Birazdan birlikte demetler (Tuples, Ali hocanın kitabında Çokuzlular) gibi bir şey deneyeceğiz. Zaten Ali hoca da demiş:

"O çokuzlu türünün aşağıdaki sözde yapının eşdeğeri olduğunu ve perde arkasında da öyle gerçekleştirildiğini düşünebilirsiniz:"
http://www.ddili.org/ders/d/cokuzlular.html

İşlevleriniz içinde tek kullanımlık ve sadece dönüş değerlerini taşımak için bulundurduğunuz bir yapı düşünün, nasıl yani! Bu konu şurada işlenmiş:

https://dlang.org/spec/struct.html#nested

Ancak konuyu with() kolaylığı ile birlikte geliştirirsek; bu yapı (struct), adeta Tuple ile yarışırcasına D programlama dilinde şu şekilde kodlanabilir:

auto getPoint()
{
  uint i = 7;

  struct Px
  {
    uint x, y;
    string d = "Koordinatlar: ";

    uint sum() { return x + i + 1; }
    auto get() { return this; }
  }

  with(Px()) { x = 3; y = sum; return get; }/*
  Px p;
  p.x = 3;
  p.y = p.sum();
  return p;//*Yukarda tek satırda bunlar var!*/
}

import std.stdio;

void main()
{
  with(getPoint) writefln!"%s %d, %d"
                           (d, x, y);

  getPoint.x.writeln(": X");
  getPoint.y.writeln(": Y");
}

Nasıldı? Hoş değil mi!

Sizce de elimizin altında olan basit ama şaşırtıcı bir uygulama değil mi? Hatta gerektiğinde alışkanlık veya geleneksel manada standart tarzımız haline gelse nasıl olurdu? Peki bu geri döndürdüğümüz veri POD mudur? Eğer öyleyse fazla sistem kaynağı harcamasa gerek:

https://dlang.org/spec/struct.html#POD

Teşekkürler...

January 30, 2022

On Sunday, 30 January 2022 at 09:28:20 UTC, Salih Dincer wrote:

>

Nasıldı? Hoş değil mi!

Sizce de elimizin altında olan basit
ama şaşırtıcı bir uygulama değil mi?

Ama bir şeyi vurgulamalıyı unuttum:

İşlevi her çağırdığınızda, döndürdüğünüz yapı, birbirlerinden bağımsız tekrar oluşturulur; tabi bunu bir değişken üzerinden (ya da aşağıdaki örnekteki gibi with bloğu içindeyken) yaparsanız başka. Yani etkisi devam eden uygulamalar için doğrudan işleve erişmek yerine, döndürdüğü yapıya (yaşayan değişken ile) işaret etmek gerekir.

Yine aşağıda yapıya eklediğim ve işlevin içindeki değişkene erişmemi sağlayan ref türündeki işleve dikkat! Burda ise başka bir dolap(sihir) dönmekte.

Nasıl, lezzetli mi!

// Yapıya eklendi: ref uint iExt() { return i; }
void main()
{
  with(getPoint) {
    writefln!"%s %d, %d"(d, x, y);
    // i = 42; // normalde bu tanımsız!
    iExt = 42; // ama ref üye tanımlarsak:
    sum.writeln; // 46 elde ederiz!
  }
  getPoint.x.writeln(": X"); // 2. kopya
  getPoint.y.writeln(": Y"); // 3. kopya
}
January 30, 2022
On 1/30/22 01:28, Salih Dincer wrote:

> ```d
> auto getPoint()
> {
>    uint i = 7;
>
>    struct Px
>    {
>      uint x, y;
>      string d = "Koordinatlar: ";

Eğer her nesne için aynı değeri taşıyacaksa d'nin static olmasında yarar var. Yoksa, Px'in boyunu arttırmaktan başka bir işe yaramaz.

Bunu ben de kullanıyorum. Hatta duruma göre daha kısa da olabiliyor:

import std.stdio;

auto foo() {
  import std.typecons : tuple;
  return tuple!("x", "y")(1, 2);
}

void main() {
  auto nokta = foo();
  writeln(nokta.x);
}

> Nasıldı? Hoş değil mi!

Evet, bunlar çok kullanışlı olabiliyor. Bunları deneme amacıyla yazdığını biliyorum ama kimse her satırını düşüne düşüne anlayacağımız aşağıdaki gibi kodlar yazmaz. :)

>  with(Px()) { x = 3; y = sum; return get; }/*

y'nin değeri nedense sum() işlevinden gelecek ve nesnenin kendisini get() işlevinden alacağız. Bir nedeni varsa tamam ama açıklık en önemli şeylerden birisidir. :)

> Sizce de elimizin altında olan basit ama şaşırtıcı bir uygulama değil
> mi?

Çok! :) Döndürülen nesne işlev içindeki veya başka yerdeki veriyi kullanınca daha da kullanışlı olur. Ama o zaman POD olmaz (aşağıda.)

> Hatta gerektiğinde alışkanlık veya geleneksel manada standart
> tarzımız haline gelse nasıl olurdu? Peki bu geri döndürdüğümüz veri POD
> mudur?

isPOD var:

  pragma(msg, __traits(isPOD, typeof(getPoint())));

Senin tür POD değil çünkü gösterdiğin bağlantıdaki iki maddeyi ihlal ediyor:

Seninki "nested" ve açık olmasa da 'ref' üyeleri var çünkü işlev içindeki i'yi daha sonradan kullanıyor. O işlevin "içi", salt döndürdüğü nesneler sonradan kullanacak diye dinamik bellekten ayrılır. Ve döndürülen türün o işlevin içine bir referansı vardır. (sum() her çağrıldığında i bilinebilsin diye.) (Ben "nested"a "iç tanım" demişim.) Böyle türlerin o kapsamı gösteren gizli bir üyesi olur ve o yüzden POD'den daha büyüktürler.

Derleyici, çoğu durumda yapı tanımına bakarak iç tanım olmadığını anlayabilir. (Ama burada i yüzünden iç tanım olmak zorundadır.)

Yapının iç tanım olmasını istemiyorsak başına açıkça 'static' de yazabiliriz:

static struct Px {
  // ...
}

O zaman derleyici, istediğimiz olamadığında hata verir.

Ali

January 30, 2022
On 1/30/22 8:02 AM, Ali Çehreli wrote:

> Senin tür POD değil çünkü gösterdiğin bağlantıdaki iki maddeyi ihlal
> ediyor:

Orada hatalıyım. Senin türün POD kurallarını ihlal ettiği tek nokta, iç tanım olması. Çünkü ref üyeleri yok. Baştan string'in ref üye kabul edileceğini düşünmüştüm ama isPOD yine de true döndürüyor. (?)

Ali


January 30, 2022

On Sunday, 30 January 2022 at 16:02:47 UTC, Ali Çehreli wrote:

>

On 1/30/22 01:28, Salih Dincer wrote:

>

Nasıldı? Hoş değil mi!

Evet, bunlar çok kullanışlı olabiliyor. Bunları deneme amacıyla yazdığını biliyorum ama kimse her satırını düşüne düşüne anlayacağımız aşağıdaki gibi kodlar yazmaz. :)

Evet hocam bunlar sadece bir deneme. Hatta benim Deney22 (o kadar şey yok, 22 içinde bulunduğumuz yıl) dizini içinde başkaları da var! Şimdi baktım, önceki heapSort.d imiş ve önümüzdeki haftayı iple çekiyorum. Şu görüntülü sohbet duyurusunu yapsak mı artık? Aralıklar ve AVL Tree hakkkında soracaklarım var :)

> >
 with(Px()) { x = 3; y = sum; return get; }/*

y'nin değeri nedense sum() işlevinden gelecek ve nesnenin kendisini get() işlevinden alacağız. Bir nedeni varsa tamam ama açıklık en önemli şeylerden birisidir. :)

Genelde tek satırları basit görünmesi için yapıyorum. Ben zihnimde onları (Zihin Paketi) kapıyorum! Evet, başkaları için okunabilirliliği düşürüyor ama hemen altına benzerini açıklama satırını koydum.

Zihin Paketi de ne! Benim için şu:

"O satırı unut, okuma ve hiç değiştirme de! O orda olması gerekiyor ve işe yarıyor. Anlamak için çok istersen altındaki açıklamasını oku ya da başına // koy ve kapa altındaki çoklu satırları (genelde eşdeğeri) açığa çıkar. Gerekiyorsa paketi devre dışı bırak ya da anlamadıysan kurcalama o zihinden çıkarıp paketlediğin bir kod parçası. Kurcalama, lazım o ve anlamak için vaktini harcama, dursun" :))))))

İşte böyle :)

> >

Hatta gerektiğinde alışkanlık veya
geleneksel manada standart tarzımız
haline gelse nasıl olurdu? Peki bu
geri döndürdüğümüz veri POD mudur?

isPOD var:

pragma(msg, __traits(isPOD, typeof(getPoint())));

Senin tür POD değil çünkü gösterdiğin bağlantıdaki iki maddeyi ihlal ediyor:

Seninki "nested" ve açık olmasa da 'ref' üyeleri var çünkü işlev içindeki i'yi daha sonradan kullanıyor. O işlevin "içi", salt döndürdüğü nesneler sonradan kullanacak diye dinamik bellekten ayrılır. Ve döndürülen türün
o işlevin içine bir referansı vardır.

Teşekkürler hocam, bunları bilmiyordum ve Pi Ooo Dii (POD) olayını yeni öğrendim.

>

Böyle türlerin o kapsamı gösteren
gizli bir üyesi olur ve o yüzden
POD'den daha büyüktürler.

Bu durumlara ve static kullanımına özen göstereceğim. Henüz, hizalama(align), bellek yönetimi araçlarına ve yardımcı işlev kulanımına yeni başladım. Hepsi harika şeyler!

Sevgiler...