Aliases

Reiner Pope reiner.pope at REMOVE.THIS.gmail.com
Mon Oct 23 21:19:34 PDT 2006


Walter Bright wrote:
> The first one works as:
> 
>> class Foo
>> {
>>     int[2] nodes;
>>     int left() { return nodes[0]; }
>>     int right() { return nodes[1]; }
>> }
Except that this doesn't support writing of the nodes. For that, you 
would need to write property setters as well, making the code:

class Foo
{
     int[2] nodes;
     int left() { return nodes[0]; }
     int left(int val) { return nodes[0] = val; }
     int right() { return nodes[1]; }
     int right(int val) { return nodes[1] = val; }
}

which is much more verbose than the (impossible) alias version:

class Foo
{
     int[2] nodes;
     alias nodes[0] left;
     alias nodes[1] right;
}

Never worry, I thought I would try to make a mixin that supports it:

template readerWriter(alias b)
{
   private alias typeof(b) T;
   T rw() { return b; }
   T rw(T val) { return b = val; }
}

struct Foo
{
   int[2] stuff;
   mixin readerWriter!(stuff[0]) _left;
   alias _left.rw left;
   mixin readerWriter!(stuff[1]) _right;
   alias _right.rw right;
}

Except for the renaming-of-mixins issue (that argument's for another 
day), the code would have been pretty simple, except that it doesn't 
work for pretty much the same reason -- you can't alias this kind of thing.

And, of course, you have all the normal property issues:
   - you can't be sure they'll be inlined
   - you can't do left++
   - you can't do 'auto val = left;'


> 
> And the other:
> 
>> class Foo
>>   {
>>     void DoSomething() { }
>>   }
>>
>>   class FooHandle
>>   {
>>     Foo myFoo;
>>     void DoSomething() { myFoo.DoSomething(); }
>>   }
> 

I agree, there's not much problem with this, but here it's a question of 
convenience and consistency: we can use alias to forward local functions 
(presumably because you decided it wouldn't be too hard to do, and 
changing the signatures is a pain which could be avoided) yet we can't 
use it to forward non-local functions. In fact, it can get much more 
complex than that, if you have a lot of overloads, or a function 
signature which changes a lot:

class MyPrinter
{
   void print(int) {}
   void print(char) {}
   void print(char[]) {}
    ...
}

class PrinterHandle
{
    MyPrinter p;
    alias p.print print;
}

as opposed to

class PrinterHandle2
{
    MyPrinter p;
    void print(int val) { p.print(val); }
    void print(char val) { p.print(val); }
    void print(char[] val) { p.print(val); }
    ...
}

While I do think that (if just for consistency's sake) we shouldn't have 
this restriction on aliases, I realise that this is a problem of 
syntactical optimization, and the best approach (again) would be to 
embody a form of metaprogramming which could support this sort of thing 
in libraries because this is not the only syntactical inefficiency in 
the language, and we need some much more extensible way to remove such 
inefficiencies; I think Nemerle could be a good place to look for such a 
metaprogramming/macro system.

Cheers,

Reiner



More information about the Digitalmars-d mailing list