Thread overview
const: Sadece bir deneme
Mar 30, 2022
Salih Dincer
Mar 30, 2022
Ali Çehreli
Mar 31, 2022
Salih Dincer
Mar 31, 2022
Salih Dincer
Mar 31, 2022
Ali Çehreli
March 30, 2022

Merhaba,

Sadece const'u anlamak için long.max sınırları içinde kalan Mp = 2 ^ n - 1 Mersenne asallarını hesaplar ve sonunda ilginç sonuçlar çıkar...

/***
 * 6. Mp,
 * n = 17:
 * 131071 de asal bir sayıdır
 *
 **********************************/

class MersennePrime
{
  const long C;
  long e, c;

  this(long e, const long C)
  {
    this.e = e;
    this.C = C;
    this.c = C;
  }

  const
  {
  //                   1a => long
    auto constTestc()   { return (2^^e) + c; }

  //                   1b => long
    auto constTestc_i() { return cast(const long)(2^^e) + cast(int)c; }

  //                   1c => const(long)
    auto constTestc_cc() { return cast(const long)(2^^e) + c; }
  }
  //                   1d => long
  auto constTestc_c()   { return cast(const long)(2^^e) + c; }


  //                   2a => const(long)
  auto constTestC() { const result = 2^^e; return result + C; }

  //                   2b => long
  auto constTestc_I()   { return cast(const long)(2^^e) + cast(int)C; }

  //                   2c => long
  auto constTestc_II()  { return cast(const long)(2^^e) + cast(const int)C; }

  //                   2d => const(long)
  auto constTestc_C()   { return cast(const long)(2^^e) + C; }
}

enum : long {
  l = 17,//61,
  a = -1
}

import std.stdio;
void main()
{
  // Access Via Object :
  auto Mp = new MersennePrime(l, a);

  typeid(Mp.constTestc).writeln(", 1a: ",    Mp.constTestc);    // long
  typeid(Mp.constTestc_i).writeln(", 1b: ",  Mp.constTestc_i);  // long
  typeid(Mp.constTestc_cc).writeln(", 1c: ",  Mp.constTestc_cc);  // const(long)
  typeid(Mp.constTestc_c).writeln(", 1d: ", Mp.constTestc_c); // long
  writeln;

  typeid(Mp.constTestC).writeln(", 2a: ",    Mp.constTestC);    // const(long)
  typeid(Mp.constTestc_I).writeln(", 2b: ",  Mp.constTestc_I);  // long
  typeid(Mp.constTestc_II).writeln(", 2c: ", Mp.constTestc_II); // long
  typeid(Mp.constTestc_C).writeln(", 2d: ",  Mp.constTestc_C);  // const(long)

  // Access Via Local Function:

  auto constTestc() const {
  return 2 ^^ l + a;
  }
  auto constTestcc() const {
  const result = 2^^l;
    return result + a;
  }

  auto constTestc_c() const {
    return cast(const long)(2) ^^ l + a;
  }
  writeln;

  typeid( constTestc() ).writeln(": ", constTestc); // long
  typeid( constTestcc() ).writeln(": ", constTestc); // long
  typeid( constTestc_c() ).writeln(": ", constTestc_c); // long
} /* ÇIKTISI:
long, 1a: 131071
long, 1b: 131071
const(long), 1c: 131071
long, 1d: 131071

const(long), 2a: 131071
long, 2b: 131071
long, 2c: 131071
const(long), 2d: 131071

long: 131071
long: 131071
long: 131071
*/

Öncelikle yapamadığım 2 bilgi:

  • 1.'si, main() veya bir yapı/sınıf dışında serbest işleve const veremiyorsunuz. Şu hatayı alıyorum:
>

without this cannot be const

  • 2.'si, main() içinde const { // ... } bloğu çalışmıyor. Hemen yukarda denediğim gibi bir işe yaramasa da hatasız kabul ediyor.

Asıl işe yaradığı olasılıkları sınıf içinde görmekteseniz. Ama nedense, sadece 1c, 2a ve 2d'de const döndürebildim. Elbette başka olasılıklar da (const döndüren vardır ama nedense şu olasılıklarda bir türlü const döndürülemiyor:

  • 1a: Tabii ki de bu normal, auto özelliği const çıkarsayamaz ama dıştaki const bloğu ne yapar diye merak ettim.

  • 1b: Dönüşü yapılan toplamlardan soldaki const. Ve evet sağdaki değil ama dikkat türü int. Sanki farklı türde 2 değişken toplanırsa dıştaki const etkisiz kalıyor. Çünkü sonraki 1c'de bunu görmemekteyiz: const long + long sorun yok.

  • 1d: Bu 1c ile büyük çoğunlukla aynı tek farkı const bloğu içinde olmaması. O yüzden etkisini göremiyoruz.

  • 2b: Tıpkı 1b'deki gibi const long + int toplanıyor. Bu yüzden const bloğu içinde olması hiçbir şeyi değiştirmezdi.

  • 2c: Ama bu şaşırtıcı çünkü her ikisi de const. Hatta const bloğu içinde olsaydı bile bir şey değişmeyecekti.

Aslında 2a ile ile 2d birbirinin aynısı. Dolayısıyla toplanan değerler const ise çıkış da const olabildiğini görüyoruz. Ama 2 üssü int bir sayı const olmayı etkilemiyor ve sanırım tabanın const olması yeterli.

Başarılar...

March 30, 2022
On 3/30/22 12:30, Salih Dincer wrote:

> * 1.'si, main() veya bir yapı/sınıf dışında serbest işleve const
> veremiyorsunuz. Şu hatayı alıyorum:
>> without `this` cannot be `const`

Üye işlevlere uygulanan 'const', aslında 'this' değişkenini const hale getirir (ve dolayısıyla bütün üyeleri).

> * 2.'si, main() içinde const { // ... } bloğu çalışmıyor. Hemen yukarda
> denediğim gibi bir işe yaramasa da hatasız kabul ediyor.

Bazı belirteçlerde böyle eksikliklerden şikayet edildiğini hatırlıyorum. Demek ki 'const {}' (ve 'const:') ancak üyeler için kullanılabiliyor.

Uzaktan ilgili olarak, D bir de belirteçler konusunda fazla serbest olabilir: Anlamsız karışımlar olsa bile izin verir.

> Asıl işe yaradığı olasılıkları sınıf içinde görmekteseniz. Ama nedense,
> sadece 1c, 2a ve 2d'de const döndürebildim.

Bence hiçbirisi 'const' olmasa daha kullanışlı olur :) çünkü hepsi de üyelerden bağımsız yepyeni bir değer döndürüyor. Yepyeni döndürülen o değer çağıranın ortamına kopyalanacaktır. Ben kim oluyorum da çağıranın kendisine ait olan kopyayı değiştirme işine karışıyorum? :)

Başka örneklerde döndürülen değer "indirection" içerebilir. Yani, örneğin bir yapı nesnesidir ve içinde başka değiskenlere referans taşıyordur. İşte o zaman, 'const' olarak döndürülen nesnenin üyelerinin const olmasını beklerim ve çağıran kişi döndürdüğüm nesnenin üyesini değiştirememelidir.

> * 1a: Tabii ki de bu normal, auto özelliği const çıkarsayamaz ama
> dıştaki const bloğu ne yapar diye merak ettim.

O const bloğu, 'this''i işlevler içinde 'const' yapar.

> * 1b: Dönüşü yapılan toplamlardan soldaki const. Ve evet sağdaki değil
> ama dikkat türü int. Sanki farklı türde 2 değişken toplanırsa dıştaki
> const etkisiz kalıyor.

Bana o 'const' "dıştaki" gibi görünmüyor. O yalnızca toplamdaki terimlerden ilkini etkiler.

> Çünkü sonraki 1c'de bunu görmemekteyiz: const
> long + long sorun yok.

Galiba orada hem ilk değer hem de üye 'c' const olduğu için öyle.

> * 2c: Ama bu şaşırtıcı çünkü her ikisi de const. Hatta const bloğu
> içinde olsaydı bile bir şey değişmeyecekti.

Evet şaşırtıcı. Ama dediğim gibi, bunlar iyi örnek olmamalı çünkü burada "indirection" yok.

Ali

March 31, 2022

On Wednesday, 30 March 2022 at 20:28:00 UTC, Ali Çehreli wrote:

>

Üye işlevlere uygulanan 'const', aslında 'this' değişkenini const hale getirir (ve dolayısıyla bütün üyeleri).

Evet bunu, bir keresinde override string toString const {} gerçekleşmesinde görmüştüm.

On Wednesday, 30 March 2022 at 20:28:00 UTC, Ali Çehreli wrote:

>

Uzaktan ilgili olarak, D bir de belirteçler konusunda fazla serbest olabilir: Anlamsız karışımlar olsa bile izin verir.

Bu belki iyi bir şey, belki de değil?Bilemiyorum ama customize attributes nedeniyle bilerek esnek bırakılmış olabilir.

On Wednesday, 30 March 2022 at 20:28:00 UTC, Ali Çehreli wrote:

>

Bence hiçbirisi 'const' olmasa daha kullanışlı olur :) çünkü hepsi de üyelerden bağımsız yepyeni bir değer döndürüyor. Yepyeni döndürülen o değer çağıranın ortamına kopyalanacaktır. Ben kim oluyorum da çağıranın kendisine ait olan kopyayı değiştirme işine karışıyorum? :)

Örneğin çağırana ait olmayan bir dilim olabilir. Değiştirilmemesi geren bir diziden kesilen her üyeyi özgürce okuması ama değiştirmemesi istenebilir. Çünkü const olmayan bir dilim çok tehlikeli olabilir, örneğin bir IP adresin döndüren basit bir şey yazayım:

struct IP_Manager
{
  private ubyte[][] IPs = [ [ 192, 168, 255, 255 ],
  [ 192, 168, 0, 11 ], [ 192, 168, 0, 22 ] ];

  public auto getIP(size_t i) const
  {
    return IPs[i];
  }
}

import std.stdio;
void main()
{
  auto test = IP_Manager();
  auto myIP = test.getIP(1);
  typeid(myIP).writeln(myIP);
  // myIP[3] = 3; // Error: cannot modify
                  //`const` expression `myIP[3]
} /* ÇIKTISI:
  const(const(ubyte)[])[192, 168, 0, 11]
*/

On Wednesday, 30 March 2022 at 20:28:00 UTC, Ali Çehreli wrote:

>

Başka örneklerde döndürülen değer "indirection" içerebilir. Yani, örneğin bir yapı nesnesidir ve içinde başka değiskenlere referans taşıyordur.

Kitapta "indirection" ile ilgili bilgi mevcut mu? Örneğin göstergeler dersine mi nakmam gerekiyor?

On Wednesday, 30 March 2022 at 20:28:00 UTC, Ali Çehreli wrote:

>

Evet şaşırtıcı. Ama dediğim gibi, bunlar iyi örnek olmamalı çünkü burada "indirection" yok.

Acaba const özelliğinin gerçekten faydalı olduğunu gösteren örnek bir uygulama var mı?

Teşekkürler...

March 31, 2022

On Thursday, 31 March 2022 at 06:32:40 UTC, Salih Dincer wrote:

>
struct IP_Manager
{
  private ubyte[][] IPs = [ [ 192, 168, 255, 255 ],
  [ 192, 168, 0, 11 ], [ 192, 168, 0, 22 ] ];

  public auto getIP(size_t i) const
  {
    return IPs[i];
  }
}

Bunun dilim döndüren bir versiyonunda const olduğu için şu hatayı veriyormuş:

>

Error: slice test.getIP(1LU)[] is not mutable

March 31, 2022
On 3/30/22 23:32, Salih Dincer wrote:

> Kitapta "indirection" ile ilgili bilgi mevcut mu?

Yok. :/

> Örneğin göstergeler dersine mi nakmam gerekiyor?

Bence hem oradan hem de referanslarla ilgili bölümlerden çıkarsanacak bir kavram. Genel olarak "başka değişkenlere bir biçimde erişim sağlama" diyebiliriz. Wikipedia'da varmış ve evet, ilk olarak gösterge açıklamasını kullanıyor:

  https://en.wikipedia.org/wiki/Indirection

Ali