www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - static alias this

reply "Mike" <none none.com> writes:
Consider this simple example
A)-----------------------------------------
struct StaticRegister {
     static private uint _value;
      property static uint value() { return _value; }
      property static void value(uint v) { _value = v; }
}

void main(string[] s) {
     StaticRegister = 1;
     assert(StaticRegister == 1);
}
-------------------------------------------

This gives two errors for each line in `main` (exactly what I 
expected).

   test.d(8): Error: StaticRegister is not an lvalue
   test.d(9): Error: incompatible types for ((StaticRegister) == 
(1)):
   cannot use '==' with types


However, if I modify the example by adding an `alias this` ...
B)-----------------------------------------
struct StaticRegister {
     static private uint _value;
      property static uint value() { return _value; }
      property static void value(uint v) { _value = v; }

     alias value this;
}

void main(string[] s) {
     StaticRegister = 1;
     assert(StaticRegister == 1);
}
-------------------------------------------

... the assignment error is eliminated, but the read is not.

   test.d(11): Error: incompatible types for ((StaticRegister) == 
(1)):
   cannot use '==' with types

I argue that either both errors should be eliminated, or neither 
should be eliminated.  One could also argue that some variation 
of the following should be required...
    * static alias value this;
    * alias static value this;
    * alias value static this;
   ... to distinguish it from non-static `this`

Now, in the example below, `this` is referring to the type itself 
in a static context
C)-------------------------------------------
import std.stdio;

struct StaticRegister {
     static string GetType() { return typeof(this).stringof; }
}

void main(string[] s) {
     writeln(StaticRegister.GetType());
}
-------------------------------------------

So, it follows that the example below should work... and it does
D)-------------------------------------------
struct StaticRegister {
     static private uint _value = 0;
      property static uint value() { return _value; }
      property static void value(uint v) { _value= v; }

     static uint GetValue() {
         return this.value;
     }
}

void main(string[] s) {
     assert(StaticRegister.GetValue() == 0);
}
-------------------------------------------

So, why does `alias this` in a static context (See example B 
above) only half-work?  Bug?  If not, what's the design rationale?

Thanks,
Mike
Feb 07 2015
next sibling parent "jkpl" <jkpl nowhere.ut> writes:
Another try

E)-------------------------------------------
struct StaticRegister {
     static private uint _value;
      property static uint value() { return _value; }
      property static void value(uint v) { _value = v; }
     static uint opCall(){return _value;}
     alias _value this;
}

void main(string[] s) {
     StaticRegister = 1;
     assert(StaticRegister()==1);
}

Yes you're right, it's a bit strange that the writer works...does 
the expression 'static this' make sense ?!
Feb 07 2015
prev sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 02/07/2015 04:46 AM, Mike wrote:

 B)-----------------------------------------
 struct StaticRegister {
      static private uint _value;
       property static uint value() { return _value; }
       property static void value(uint v) { _value = v; }

      alias value this;
 }

 void main(string[] s) {
      StaticRegister = 1;
      assert(StaticRegister == 1);
 }
 -------------------------------------------

 ... the assignment error is eliminated, but the read is not.
I bet it's an unintentional implementation artifact. Assigning to a type doesn't make sense to me.
 I argue that either both errors should be eliminated, or neither should
 be eliminated.
It is not hard to create strange D code. I recommend the following lightning talk for fun. :) Brian Schott at DConf 2014: http://www.youtube.com/watch?v=oF8K4-bieaw#t=1620
 Now, in the example below, `this` is referring to the type itself in a
 static context
Not exactly "type itself" because you apply typeof() to it later below. I this 'this' means "the type of the object if it were not a static function". :/
 C)-------------------------------------------
 import std.stdio;

 struct StaticRegister {
      static string GetType() { return typeof(this).stringof; }
 }

 void main(string[] s) {
      writeln(StaticRegister.GetType());
 }
 -------------------------------------------

 So, it follows that the example below should work... and it does
 D)-------------------------------------------
 struct StaticRegister {
      static private uint _value = 0;
       property static uint value() { return _value; }
       property static void value(uint v) { _value= v; }

      static uint GetValue() {
          return this.value;
That works by accident. I am surprised that 'this' works in a static function. In any case, it should better be null. Ok, it's good that 'this' is not available: assert(this is null); Error: 'this' is only defined in non-static member functions, not foo Phew... :) So, 'this.value' works by accident because the compiler reaches for *static* value() without evaluating 'this'. Ali
Feb 07 2015