Thread overview
enum'larda beklenen bir kalıtım yok!
Dec 04, 2022
Salih Dincer
Dec 04, 2022
Salih Dincer
Dec 04, 2022
Ali Çehreli
Dec 05, 2022
Salih Dincer
Dec 05, 2022
Salih Dincer
December 04, 2022

Merhaba,

En son, AA (associative array) ve enum çerçevesinde şu konuya değinmiştim:

enum'lara nitelikli CT işlevi yükleme

Aslında orada, normalde çalışma zamanı (RT) ilklenen ilişkisel dizi(AA)'nin D içine yedirilmiş çok güzel bir derleme zamanı (CT) olanağını görüyoruz. Şimdi ise farklı bir konuya gireceğiz!

AŞAĞIDAKİ BİR D KODU DEĞİLDİR

enum Foo
{
     a0 = 1,
     a1
}

enum Bar: Foo
{
    a2 // 3
}

YUKARDAKİ BİR D KODU DEĞİLDİR

Ama kod D'de derlenir! Bilmem derlenmeli midir çünkü türü belirleme özelliğine ihtiyacımız da var. Yine beklendiği gibi kalıtım almayacağını bilin yeter. İşte bir uygulamalı örnek:

void main()
{
  char[] hex;
  enum Hex : char {
    h0 = 48, h1, h2, h3, h4, h5, h6, h7, h8, h9,
    a10 = 65, b11, c13, d14, e15, f16
  }

  with(Hex) {
    hex = [
      h0, h1, h2, h3, h4, h5, h6, h7, h8, h9,
      a10, b11, c13, d14, e15, f16
    ];
  }
  enum Num : Hex { num }

  hex ~= [Num.num.a10];

  assert(Hex.a10 == 65);
  assert(Num.num == 0);

  import std.stdio;
  writeln(hex); // 0123456789ABCDEFA
}

Yakında ilgi duyan olursa CT örneklerine başlayacağım. D'nin büyüsüne kapılma zamanı!

Başarılar...

December 04, 2022

On Sunday, 4 December 2022 at 10:48:45 UTC, Salih Dincer wrote:

>

Yine beklendiği gibi kalıtım almayacağını bilin yeter.

Beynim yandı galiba 😀

Hastayım ve üzgünüm yeterince deneme yapmadan yanlış bilgiyi paylaştım. Sanırım tıpkı sınıflarda olduğu gibi (bu aşamada başlık değişmeli!) enum'larda kalutım var! İşte kanıtlayan basit bir örnek:

import std.stdio;

enum para { YAZI, TURA }
enum q : para { Dik }

void main()
{
    auto dik = q.Dik;
    auto foo = dik ? true : false;
    foo.writeln(": ", [dik]);

    auto tura = q.TURA;
    auto bar = tura ? true : false;
    bar.writeln(": ", [tura]);
} /* ÇIKTISI:
false: [Dik]
true: [TURA]
*/

Açıklama yapabilecek olan, şimdi biraz dinlemeliyim. Yarın iş var ve başımçatlıtor...

December 04, 2022
On 12/4/22 08:43, Salih Dincer wrote:

> kanıtlayan basit bir örnek:

Ben çok akıllı birisi değilimdir ama örneğin basit olmadığında ısrarlıyım. Evet, kod kısa ve kullanılan olanaklar basit ama senin tam olarak neyi göstermek istediğini açıklamada yetersiz kalıyor.

> enum para { YAZI, TURA }

Onu çok kolay anlıyorum. Tamam...

> enum q : para { Dik }

O noktada kafam karışmaya başlıyor: Neden bu sefer anlaşılır bir tür ismi değil de q? Dik ne anlama geliyor?

Belki gereksizce takılıyorum ama bunlar kafada soru işaretleri başlattıklarından anlamayı güçleştiriyorlar.

>      auto dik = q.Dik;

O bile karışık: Değişkenin ismi değerle aynı olmamalı, değil mi? Örneğin şöyle yazarız:

  auto atış = para.YAZI;

Ama şöyle yazmayız:

  auto yazı = para.YAZI;

Yani, 'q.Dik' değerini alan değişken neden 'dik'?

>      auto foo = dik ? true : false;
>      foo.writeln(": ", [dik]);

Elemanı 'dik' olan dizi oluşturmanın bu konuyla ilgisi var mı? Belki yok. Belki çıktıda dizi olarak görmeyi seviyorsun. (?) Ama kodu okuyan kişiler bunlara dikkat etmek zorundalar. Ben, alnım kırışmış biçimde anlamaya çalışıyorum.

> } /* ÇIKTISI:
> false: [Dik]
> true: [TURA]
> */

Peki o çıktı istediğin gibi mi oldu yoksa beklenenden farklı bir şey mi oldu? Onu bile anlamaya çalışıyorum.

> Açıklama yapabilecek olan

Konuyu tam anlayabilsem fikrim olacağından eminim.

Bu arada, başlıkta nesne yönelimli programlamadan bildiğimiz "kalıtım" geçiyor. enumlarda da aynı anlamda kullanmıyoruz, değil mi? Otomatik atanan değerlerin devam ettirilmesinden mi bahsediyoruz?

Ali

December 05, 2022

On Sunday, 4 December 2022 at 17:57:57 UTC, Ali Çehreli wrote:

>

...örneğin basit olmadığında ısrarlıyım.

Hocam, yerden göğe kadar haklısınız! Virüs beynimi kemirmeye ara verdiği şu saatlerde (sabahın 4'ü 😀) örneği biraz geliştirdim. Akılda en ufak soru bırakmayacak şekilde ve tüm D olanaklarını kullanarak test ettim:

import std.range, std.random : uniform;
import std.stdio;

enum Para : char { Yazı = 48, Tura }

void main()
{
  enum ÖzelPara : Para
  {
     dik = cast(Para)124, // ASCII: | (Superposition)
     sfr = Para.Yazı,     // ASCII: 0 (False)
     bir = Para.Tura      // ASCII: 1 (True)
  }
  auto r = gen!(function char() =>
           uniform!ÖzelPara/*
           uniform!Para//*/
  );
  r.take(12).writefln!"[%s]";

// } unittest {

  import std.conv : asOriginalType;
  ÖzelPara.Tura.asOriginalType.writeln; /*
    ^-- bunun Tura diye bir üyesi yok ama
  Para'nın Yazı, ÖzelPara'nın sfr üyesi var:
  */
  Para.Yazı.asOriginalType.writeln;    // 0
  ÖzelPara.sfr.asOriginalType.writeln; // 0

  // aslında ÖzelPara'nın sadece 3 üyesi yok mu?

  import std.traits : EnumMembers;
  foreach(i, member; [EnumMembers!ÖzelPara])
  {
    write(i + 1);
    member.asOriginalType.writefln!": %s";
  }
} /* 1, 2, 3! varmış 😀

İŞTE UNITTEST ÇIKTISI:
1
0
0
1: |
2: 0
3: 1
*/
template gen (alias fn) {
  struct GenRes { //
    import std.traits;
    ReturnType!fn func;
    enum empty = false;
    auto front() { return func; }
    void popFront() { func = fn(); }
  }
  GenRes gen() {
    auto gen = GenRes();
         gen.popFront();
    return gen;
  }
}
>

Notlar:

  • Eğer ÖzelPara'nın 3.'cü üyesini boş bırakırsanız şu hatayı alırsınız:
    (Bence almamalısınız! Neden böyle?)
enumYAZITURA.d(12): Error: Comparison between different enumeration types `ÖzelPara` and `Para`; If this behavior is intended consider using `std.conv.asOriginalType`

Soru ve açıklamalarımı sonraki iletiye sakladım. Kalıtım konusunda ısrar etmeyeceğim ama açıklayacağım...

December 05, 2022

On Monday, 5 December 2022 at 01:24:40 UTC, Salih Dincer wrote:

>

... Kalıtım konusunda ısrar etmeyeceğim
ama açıklayacağım...

Öncelikle bu enumaration örneğini nereden bulduğumu ve bende yaşattığı etkiden kısaca bahsedeyim...

Basile B.'nin geliştirdiği, Sytx isminde ve çoğunlukla D'den türeyen (hatta kuramsal olarak kendi kendi gerçekleyen) bir dili varmış:
https://styx-lang.gitlab.io/styx/enum_declaration.html#.semantics

Sözdizimi açıklayan bu sayfada, enum foo'dan sonra gelen tek üyeli enum bar'ın 3 sayısını alacağını görüyoruz. Ha keza 2.0.66'dan beri (sanırım bu D1'den D2'ye geçildiği sürüm) belgelerde benzer bir örnek var ama sadece E'nin 2. üyesinin C.max'dan ötürü vereceği hatadan bahsedilmiş:

https://docarchives.dlang.io/v2.066.0/enum.html#EnumMember

Eee tabi : ile benzer nesneye bağlandığını görünce, zihin hemen OOP'da gördüğümüz kalıtım yoluyla 2 üye daha aldığını zannediyor. O yüzden beynim yandı diyorum ya ama 2 bölüm halinde geliştirdiğim örnek soruları beraberinde getiriyor! Öncelikle cevabı belli olandan başlayayım:

  1. ÖzelPara'nın, Para türünden başka hiçbir değer ile ilklenememesi: Eee, çünkü iki nokta üst üste ile bunu belirttik. Alacağı değerler, dolaylı olarak char türünde. Yani Para'nın sadece 2 üyesi olsa da aslında 256 üyeli enumaration oluşturmak olası.

  2. Pekala, neden ÖzelPara.bir kendiliğinden bir değer almadı? İşte bunu açıklayamıyorum çünkü Para.max'a henüz gelmemiştik! Bug?

  3. Ancak, neden 3 üyeli kurulan bir nesnenin sanki kalıtım yoluyla türemiş gibi 2 üyesi daha olsun? Beyin Error 😀

İyi haftalar...