Thread overview
C stili ile yapı kurma
Aug 11
Cos00kun
August 10

Merhaba,

Avantajlı yeni bir şey öğrendim, daha doğrusu keşfettim: Bugünlerde BigInt'e takılıyorum da meğer, toHex gibi özelikler ve neredeyse sınırsız kapasitesi ile ne güzel bir modülmüş! Neyse konumuza dönelim...

Aşağıdaki örnek kodda, C stili ile yapıyı kurarak (sayı1) dışarısında tanınmayan değişkenlerini eşitlemek çok kolay. Çünkü kendi dünyanızda tanıdığınız veriyi, int olarak emanet ettiğinizde BigInt türüne otomatik cast işlemi yapılıyor. Modülde bütün bunlar tanımlanmış. Sanırım string olarak da veri tanımlamak mümkün.


struct BüyükSayı {
  import std.bigint;
  BigInt a, b = 2022;

  void çarp() { a *= b; }

  string toString() {
    import std.format;
    return format("%s\n(%s)", a, a.toHex);
  }
}

import std.stdio;
void main()
{
  BüyükSayı sayı1 = { a: ulong.max };
  sayı1.çarp();

  sayı1.writeln("\n");

  auto sayı2 = BüyükSayı();
  sayı2.a = 10;
  sayı2.çarp();

  sayı2.writeln("\n");

  import std.bigint;
  auto sayı3 = BüyükSayı(
    cast(BigInt)123,
    BigInt(12345567)
  );
  sayı3.çarp();
  sayı3.writeln("\n");

  struct KuruculuBüyükSayı {
    import std.bigint;
    BigInt a;
    this(int i) { a = i; }
  } /* Error:
       struct `KuruculuBüyükSayı` has constructors,
       cannot use `{ initializers }`,
       use `KuruculuBüyükSayı( initializers )` instead
     */

  auto ikibinyirmi = KuruculuBüyükSayı(2020);
  ikibinyirmi.writeln;

  //KuruculuBüyükSayı hata = { a: 2020 };
} /* ÇIKTISI:
37299316517040713365530
(7E5_FFFFFFFF_FFFFF81A)

20220
(4EFC)

1518504741
(5A828B25)

KuruculuBüyükSayı(2020, null)
*/

Tabi kendi kurucu üyeniz this() olmaması lazım yoksa kodun sonundaki hatayı alırsınız. Gerçi bu sefer tek üyeli bir sınıf (KuruculuBüyükSayı) olmasına rağmen null olan bir üye değişken gördüm!

Bu nedir? Yoksa this() kurucusu mu?

Son bilgi (gerçi sayı3'de görülüyor), eğer C stili kullanmak istemiyorum ve varsayılan kurucu bana yeter diyorsanız, demeyin! Çünkü o zaman hem kurulduğu yerde std.bigint modülünü eklemeli, hem de kendi tür dönüşümünüzü hemen oracakta yapmalısınız.

Kolay gelsin...

August 10
On 8/10/22 04:57, Salih Dincer wrote:

> KuruculuBüyükSayı(2020, null)

[...]

> tek üyeli bir sınıf (KuruculuBüyükSayı)
> olmasına rağmen null olan bir üye değişken gördüm!

Onun nedeni, "context pointer". İç (nested) yapılar, içinde bulundukları ortamı canlı tutarlar (ve o yüzden daha masraflıdırlar).

İç yapıların normal olmaları, 'static' ile sağlanır. Aşağıdaki program farkını gösteriyor:

import std.stdio;

auto foo() {
  int i;

  struct A {
    int bar() {
      // Kendi dışındaki değişkeni döndürüyor
      ++i;
      return i;
    }
  }

  static struct B {
  }

  writeln("Birinde gösterge var:");
  writeln(A.sizeof);
  writeln(B.sizeof);

  return A();
}

void main() {
  auto a = foo();

  writeln("Dışarıdaki değişkeni kullanmaya devam ediyor:");
  foreach (_; 0 .. 5) {
    writeln(a.bar());
  }
}

Çıktısı:

Birinde gösterge var:
8
1  <---
Dışarıdaki değişkeni kullanmaya devam ediyor:
1
2
3
4
5

Ek konu: Okla işaretlediğim de ilginç bir konudur: Üyesi olmayan yapıların büyüklükleri 1'dir. Onun nedeni de bir diziye yerleştirildiklerinde aynı adreste bulunmamalarının istenmeleridir. (dizi[i], (dizi + i * T.sizeof) olduğundan, sizeof 0 olduğunda hep aynı adres çıkardı.)

Ali

August 10

On Wednesday, 10 August 2022 at 14:33:36 UTC, Ali Çehreli wrote:

>

İç yapıların normal olmaları, 'static' ile sağlanır. Aşağıdaki program farkını gösteriyor:

import std.stdio;

auto foo() {
  int i;

  struct A {
    int bar() {
      // Kendi dışındaki değişkeni döndürüyor
      ++i;
      return i;
    }
  }

  static struct B {
  }

  writeln("Birinde gösterge var:");
  writeln(A.sizeof);
  writeln(B.sizeof);

  return A();
}

void main() {
  auto a = foo();

  writeln("Dışarıdaki değişkeni kullanmaya devam ediyor:");
  foreach (_; 0 .. 5) {
    writeln(a.bar());
  }
}

Teşekkürler hocam, context pointer'ı hiç duymamıştım; hele ki Voldermort Type konusunu işlerken...

Üyesi bulunmayan statik yapıların da üyesi varmış gibi boyutu olması mantıklı görünüyor.

Bir de null ile ilgili olan bir konuda şu 2 şey farklı görünüyor:

  BigInt num; // bu bir yapı sanki ama!
  string str;
  assert(str is null); // geçti
  assert(num is null); /* Error:
    incompatible types for `(this.a) is
    (null)`: `BigInt` and `typeof(null)`*/

Bu konuyu, string için yabancı forumda tartışmıştık. Orada str = "" şeklinde kurduğumuzda null olmaktan çıkıyordu. Anladığım kadarıyla is'i kendi türlerimizde de kullanamıyoruz, değil mi?

Sevgiler, saygılar...

August 10

On Wednesday, 10 August 2022 at 11:57:09 UTC, Salih Dincer wrote:

>

... örnek kodda, C stili ile yapıyı kurarak (sayı1) dışarısında tanınmayan değişkenlerini eşitlemek çok kolay.

Kod üzerinde bir iki deneme yaparken bir şeyin farkına vardım:

Aslında,

  BüyükSayı sayı = {
                 a: 3,
                 b: 5
  };
  sayı.çarp();
  assert(sayı.a == 15);

... ile ...

  BüyükSayı sayı;
            sayı.a = 3;
            sayı.b = 5;

  sayı.çarp();
  assert(sayı.a == 15);

aynı!

GodBolt ile üretilen ikili koda bakmadım ama her ikisi de sanırım aynı görünüyor. Bir farkla o da güzel parantezlerin {..} içine şunu yapamazdınız:

  BüyükSayı sayı;
            sayı.a++; // 1
            sayı.b++; // 2023

  sayı.çarp();
  assert(sayı.a == 2023);

İşte, bu bir bakış açısı! İster sağ elinizi ensenizden dolayıp sol kulağınızı tutun, isterseniz her bir eliniz ile o taraftakini... 😀

Yine de bu tür olanaklar güzel. Bir ara şurada withMe isminde bir kolaylık işleviyle, bir dil olanağı önerisini denemiştik. Çok daha kısa olduğu için öneriye muhalif oldum. Ama kuruculara yardımcı her tür olanak çok ilgimi çekiyor. Umarım yapılar için C-style olanağını elimizden almazlar! Bazen with olanağını bile tartışmaya açıyorlar ya, kulakları çınlasın D düşmanlarının!

Çok sevdiğim with'den bahsetmişken, aynı kod:

  auto sayı = BüyükSayı();
  with(sayı) {
            a++; // 1
            b++; // 2023
    çarp();
    assert(a == 2023);
  }

İşte burda şöyle bir olay daha var. Başta kurulmuş yapı, hem with'in kapsamına sokuluyor, hem de dışından da erişilebilir oluyor.

İsteseydik with(BüyükSayı()) şekinde de kurabilir ama yukardaki olanağa sahip olamazdık. Bu arada başına new veya sonundaki ekstra parantez aç/kapa şart haberiniz olsun.

Herkese D'de başarılar...

August 10
On 8/10/22 10:15, Salih Dincer wrote:

> Teşekkürler hocam, `context pointer`'ı hiç duymamıştım;

delegate'lar da kullanırlar. Aynı kavram...

> Bir de `null` ile ilgili olan bir konuda şu 2 şey farklı görünüyor:
>
> ```d
>    BigInt num; // bu bir yapı sanki ama!
>    string str;
>    assert(str is null); // geçti
>    assert(num is null); /* Error:
>      incompatible types for `(this.a) is
>      (null)`: `BigInt` and `typeof(null)`*/
> ```

is'in o kullanımı şurada:

  https://dlang.org/spec/expression.html#identity_expressions

Referans kavramı olan türlerde 'null' ile kullanılabiliyor. Değer türlerinde ise eşitlik karşılaştırması yapıyor.

Ali

August 10
On 8/10/22 11:12, Salih Dincer wrote:

> Çok sevdiğim `with`

Ben ise hiç sevmiyorum çünkü hangi sembolün nereden geldiği anlaşılmıyor:

  with (foo) {
    a++;
    b++;
    çarp();
  }

a ve b foo ile mi ilgililer yoksa bu kapsamda daha yukarıda tanımlanmış olan değişkenler mi?

Kodu kısalttığını görüyorum ama onun başka yolları da var:

void üyeleriArttırVeÇarp(ref Foo foo) {
  foo.a++;
  foo.b++;
  foo.çarp();
}

Belki bir gün with'in işime yaradığını görürüm... :)

Ali

August 11
Şöyle profesyonel insanların arasını girip saçma sapan sorularla sizi rahatsız edeceğim için
bazan üzülüyorum ama bunu yapacağım size az kaldı :))

D dili için kesin kararımı verdim artık yarım bırakmak olmayacak ve D dilini sizinde desteğinizle iyice öğrenmeye çalışacağım.

Hedefimin ikinci kısmı aslında az önce hedeflediğimle paralel yürüyecek bir konu yani ufak çaplı bir oyun tasarlamak. Aklıma daha öncede söylediğim gibi önceleri konuştuğumuz ama bir türlü başlayamadığımız "Mangala" oyununu tasarlamak olacak. Kısa vadeli değil hiçbiri ancak başlıyorum.
Sizlerin daha önce tavsiye ettiği gibi dili öğrenmek sadece okuyarak değil uygulamayla olur bunu kendi kendime hiç Lua dili bilgisi olmadan direkt kod yazarak öğrenmiş oldum. Böylece D dilinde olmasa bile Lua dilinde bayağı bi tecrübe edinmiş oldum tabi kendimce. Şimdi o tecrübelere D dilinde programcıklar tasarlayarak devam etmek istiyorum elbette sizinde desteklerinizle..

Not: Şu Windows ile verdiğimiz savaş sebebiyle artık evimdeki laptopda hem windows hem de Ubuntu kurulu. En azından daha bi ortak dil ile konuşmuş oluruz böylece.

bu haftasonundan sonra aranızdayım artık :)