Re: Multiple subtyping with alias this and nested classes

2009-10-06 Thread Andrei Alexandrescu

Yigal Chripun wrote:

On 06/10/2009 02:15, Andrei Alexandrescu wrote:

Yigal Chripun wrote:

I think 'alias this' is a powerful feature.

Given the constraints like easy for the compiler writer to implement
and we have many other things to do, I doubt traits or something
like that will be or needs to be in the language.


Alias this is powerful black magic. being powerful doesn't make it any
less dark.


So how does this work? Alias this was meant very clearly for allowing
subtyping. Conversely, using it for subtyping is precisely how it was
meant to be used. How exactly did you decide it was a hack or black
magic or whatever?

Andrei


D already has syntax for sub-typing reference types and alias this 
introduces a completely different syntax doing the same for value types 
which is bad human interface IMO.


Inheritance is a bit more than just subtyping, for example it entails 
the prefix property (otherwise it wouldn't be very practical). That's 
why D only allows single inheritance of state; multiple inheritance of 
state causes more problems than it solves. That's also why alias this is 
a very flexible complement to inheritance - it offers subtyping without 
requiring the prefix property and leaves layout to the discretion of the 
user.


it also mixes two concepts - sub-typing and opImplicitCast (as i recall, 
this is done by alias this to a function)


opImplicitCast hasn't been implemented and probably alias this will 
render it unnecessary. I don't see a dangerous conflation.


we discussed this in the past already and IIRC you agreed with me about 
implementing compile time inheritance for structs which I feel is much 
cleaner and more consistent with the existing syntax of interfaces.


Maybe there's a misunderstanding. Inheritance of interfaces for structs 
(which is different from what alias this helps with) was something that 
Walter and I considered interesting to pursue for simplifying concept 
checking. However, recent developments clarified that that's not enough 
(I even deleted the related enhancement requests from bugzilla). 
Currently I'm considering a reflection-based concept checking, but it's 
too crude an idea to discuss it at the moment.



Andrei


Re: Multiple subtyping with alias this and nested classes

2009-10-06 Thread Max Samukha
On Tue, 06 Oct 2009 00:52:42 +0200, Yigal Chripun yigal...@gmail.com
wrote:


I see you want to discuss the details of the renaming mechanism, while I 
just talked about the general idea itself until now.

Yes, I understand the idea and am trying to imagine it in the context
of D.


we have two cases: regular and mixins.
for case a it's simple, the class itself lists the renames:

Interface A {
void foo();
}
Interface B {
void foo();
}

class C : A, B {
alias A.foo func1; // or similar syntax to mark the renaming
alias B.foo func2; // ditto

override void func1() {...} // C.func1 overrides A.foo
override void func2() {...} // C.func2 overrides B.foo
}

Ok, that looks good.


case 2, mixins:
I think some sort of annotations by the programmer is needed.

class C : A, B {
alias A.foo func1; // or similar syntax to mark the renaming
alias B.foo func2; // ditto

// hypothetical syntax to connect mixins to interfaces
// the compiler will apply the rename rules of this class assuming that
// any references to foo in ImplA are A.foo and will be renamed to
// func1 in C
// if the mixin explicitly specifies the interface (e.g B.foo) than the 
// compiler already knows what to map this to.
mixin ImplA A;
mixin ImplB B;
}

This exact syntax won't work but I see your point.


btw, this all can be done in a much simpler way with (hygienic) AST Macros.


Sadly (or for the better), we are not going to have macros in the near
future.

 I don't think I want non virtual MI in D since it is more trouble than it's 
 worth. but *if* we discuss this, I think my suggested semantics are 
 simpler. The syntax probably can be much better but that's a secondary 
 issue IMO.


 It's unrelated to virtual MI. See Sergey Gromov's post. We are
 discussing this only because it's a real world problem that has no
 decent solution in D.


I said *non* virtual MI above..

But virtual inheritance is C++'s way to resolve the diamond problem. I
don't think it is related to our discussion in any way.

This gets more and more complicated - Like I said before, I feel that 
renaming has easier to understand semantics.

As an exercise, I'm working on a mixin that will allow to subtype a
class and rename/override its virtual functions like this:

class FlippingBlipper
{
   mixin Subclass!(Flipper,
 nameCollision, foo) flipper;
   
   this() { flipper.construct(...); }

   void foo() { ... }
}

Save for some bugs in the compiler, it should work reasonably well. Or
maybe not.

 I think 'alias this' is a powerful feature.

 Given the constraints like easy for the compiler writer to implement
 and we have many other things to do, I doubt traits or something
 like that will be or needs to be in the language.

Alias this is powerful black magic. being powerful doesn't make it any 
less dark.

Could you explain why it is dark?


Re: Multiple subtyping with alias this and nested classes

2009-10-05 Thread Max Samukha
On Sun, 04 Oct 2009 12:31:08 -0400, Yigal Chripun yigal...@gmail.com
wrote:

Max Samukha Wrote:
 
 I see. What you want is non-virtual MI. 
 I don't think that allowing the derived class to have two distinct 
 implementations for the same function prototype is a good idea. 
 Eiffel handles this by giving the programmer controls to select features 
 and rename them in the derived class which I think is better. 
 
 // hypothetical syntax example
 class FlippingBlipper : IBlipper, IFilpper {
  mixin Flipper F;
  mixin Blipper B;
  // rename the inherited interface functions 
  alias IBlipper.nameCollision boo;
  alias IFilpper.nameCollision foo;
 // implement the now two distinct functions
void foo() { F.nameCollision(); }
void boo() { B.nameCollision(); }
 }
 
 you can further subtype and the derived foo  boo will override the 
 respective interfaces. 
 
 Yes, but what if nameCollision is a virtual function called somewhere
 in the template mixin? Your example has effectively removed the
 virtuality.
 

it doesn't remove virtuality. Virtual functions are stored as pointers in the 
vtable. with my suggested solution the idea is that the same pointer in the 
vtable gets a new name in the derived class. 
when you mixin the template into the derived class the compiler would  resolve 
nameCollision to the new name foo because of the renaming rule in the 
derived class. 

Ok, I still cannot see how the compiler can reliably determine that
IFlipper.nameCollision is implemented by Flipper and not by Blipper
and call the correct override when flip is called.

Should the compiler deduce that from F.nameCollision? If yes, what
about:
void foo() { B.nameCollision; F.nameCollision; } ?

Or should it decide based on the fact that Flipper contains the 'flip'
function that implements IFlipper.flip? If yes, then what if the
interfaces had nothing more than the 'nameCollision' functions?

I don't think I want non virtual MI in D since it is more trouble than it's 
worth. but *if* we discuss this, I think my suggested semantics are simpler. 
The syntax probably can be much better but that's a secondary issue IMO.


It's unrelated to virtual MI. See Sergey Gromov's post. We are
discussing this only because it's a real world problem that has no
decent solution in D.


with my design: 
class Foo : FlippingBlipper {
 override foo ...
 override bar ...
} 
IFlipper obj = new Foo; 
obj.nameCollision; // will call Foo.bar


I don't think that's possible with your design.

I'm not claiming it's my design. Andrei is the author.

And yes, it's possible in a number of ways. One is:

class BlippingFlipper
{
   class Flipper_ : Flipper
   {
 override void nameCollision()  {  foo(); }
 final void super_nameCollision() { super.nameCollision;  }
   }

   this() { flipper = new Flipper_; }

   Flipper_ flipper;
   alias flipper this;

   void foo() { flipper.super_nameCollision; }
}

class Foo : BlippingFlipper
{
override void foo() {}
}

(Wordy but still possible. Can be made easier on the eye with a helper
mixin)

I agree that possibility to implement renamed interface methods AND
explicit interface implementation would solve the problem of name
collisions. But it doesn't solve the problem of subtyping structs and
built-in types.


besides, alias this is a hack. a better mechanism would be to have 
compile-time inheritance, IMO.

I think 'alias this' is a powerful feature.

Given the constraints like easy for the compiler writer to implement
and we have many other things to do, I doubt traits or something
like that will be or needs to be in the language.


Re: Multiple subtyping with alias this and nested classes

2009-10-05 Thread Yigal Chripun

On 05/10/2009 12:19, Max Samukha wrote:

On Sun, 04 Oct 2009 12:31:08 -0400, Yigal Chripunyigal...@gmail.com
wrote:


Max Samukha Wrote:


I see. What you want is non-virtual MI.
I don't think that allowing the derived class to have two distinct 
implementations for the same function prototype is a good idea.
Eiffel handles this by giving the programmer controls to select features and 
rename them in the derived class which I think is better.

// hypothetical syntax example
class FlippingBlipper : IBlipper, IFilpper {
 mixin Flipper F;
 mixin Blipper B;
 // rename the inherited interface functions
 alias IBlipper.nameCollision boo;
 alias IFilpper.nameCollision foo;
// implement the now two distinct functions
   void foo() { F.nameCollision(); }
   void boo() { B.nameCollision(); }
}

you can further subtype and the derived foo  boo will override the respective 
interfaces.


Yes, but what if nameCollision is a virtual function called somewhere
in the template mixin? Your example has effectively removed the
virtuality.



it doesn't remove virtuality. Virtual functions are stored as pointers in the 
vtable. with my suggested solution the idea is that the same pointer in the 
vtable gets a new name in the derived class.
when you mixin the template into the derived class the compiler would  resolve 
nameCollision to the new name foo because of the renaming rule in the derived 
class.


Ok, I still cannot see how the compiler can reliably determine that
IFlipper.nameCollision is implemented by Flipper and not by Blipper
and call the correct override when flip is called.

Should the compiler deduce that from F.nameCollision? If yes, what
about:
void foo() { B.nameCollision; F.nameCollision; } ?

Or should it decide based on the fact that Flipper contains the 'flip'
function that implements IFlipper.flip? If yes, then what if the
interfaces had nothing more than the 'nameCollision' functions?

I see you want to discuss the details of the renaming mechanism, while I 
just talked about the general idea itself until now.


we have two cases: regular and mixins.
for case a it's simple, the class itself lists the renames:

Interface A {
void foo();
}
Interface B {
void foo();
}

class C : A, B {
alias A.foo func1; // or similar syntax to mark the renaming
alias B.foo func2; // ditto

override void func1() {...} // C.func1 overrides A.foo
override void func2() {...} // C.func2 overrides B.foo
}

case 2, mixins:
I think some sort of annotations by the programmer is needed.

class C : A, B {
alias A.foo func1; // or similar syntax to mark the renaming
alias B.foo func2; // ditto

// hypothetical syntax to connect mixins to interfaces
// the compiler will apply the rename rules of this class assuming that
// any references to foo in ImplA are A.foo and will be renamed to
// func1 in C
// if the mixin explicitly specifies the interface (e.g B.foo) than the 
// compiler already knows what to map this to.

mixin ImplA A;
mixin ImplB B;
}

btw, this all can be done in a much simpler way with (hygienic) AST Macros.


I don't think I want non virtual MI in D since it is more trouble than it's 
worth. but *if* we discuss this, I think my suggested semantics are simpler. 
The syntax probably can be much better but that's a secondary issue IMO.



It's unrelated to virtual MI. See Sergey Gromov's post. We are
discussing this only because it's a real world problem that has no
decent solution in D.



I said *non* virtual MI above..



with my design:
class Foo : FlippingBlipper {
override foo ...
override bar ...
}
IFlipper obj = new Foo;
obj.nameCollision; // will call Foo.bar




I don't think that's possible with your design.


I'm not claiming it's my design. Andrei is the author.

And yes, it's possible in a number of ways. One is:

class BlippingFlipper
{
class Flipper_ : Flipper
{
  override void nameCollision()  {  foo(); }
  final void super_nameCollision() { super.nameCollision;  }
}

this() { flipper = new Flipper_; }

Flipper_ flipper;
alias flipper this;

void foo() { flipper.super_nameCollision; }
}

class Foo : BlippingFlipper
{
 override void foo() {}
}

(Wordy but still possible. Can be made easier on the eye with a helper
mixin)


This gets more and more complicated - Like I said before, I feel that 
renaming has easier to understand semantics.


I agree that possibility to implement renamed interface methods AND
explicit interface implementation would solve the problem of name
collisions. But it doesn't solve the problem of subtyping structs and
built-in types.



the problem with explicit interface implementation as discussed in 
another thread is that the implementations will become hidden.


class C: A, B {
override void A.foo () { ... }
override void B.foo () { ... }
}

C obj = new C;
obj.foo(); // error

class D : C { ... }
what happens in class D? Can I override the functions there as well? how?




you do not need explicit interface 

Re: Multiple subtyping with alias this and nested classes

2009-10-05 Thread Andrei Alexandrescu

Yigal Chripun wrote:

I think 'alias this' is a powerful feature.

Given the constraints like easy for the compiler writer to implement
and we have many other things to do, I doubt traits or something
like that will be or needs to be in the language.


Alias this is powerful black magic. being powerful doesn't make it any 
less dark.


So how does this work? Alias this was meant very clearly for allowing 
subtyping. Conversely, using it for subtyping is precisely how it was 
meant to be used. How exactly did you decide it was a hack or black 
magic or whatever?


Andrei


Re: Multiple subtyping with alias this and nested classes

2009-10-05 Thread Yigal Chripun

On 06/10/2009 02:15, Andrei Alexandrescu wrote:

Yigal Chripun wrote:

I think 'alias this' is a powerful feature.

Given the constraints like easy for the compiler writer to implement
and we have many other things to do, I doubt traits or something
like that will be or needs to be in the language.


Alias this is powerful black magic. being powerful doesn't make it any
less dark.


So how does this work? Alias this was meant very clearly for allowing
subtyping. Conversely, using it for subtyping is precisely how it was
meant to be used. How exactly did you decide it was a hack or black
magic or whatever?

Andrei


D already has syntax for sub-typing reference types and alias this 
introduces a completely different syntax doing the same for value types 
which is bad human interface IMO.


it also mixes two concepts - sub-typing and opImplicitCast (as i recall, 
this is done by alias this to a function)


we discussed this in the past already and IIRC you agreed with me about 
implementing compile time inheritance for structs which I feel is much 
cleaner and more consistent with the existing syntax of interfaces.


Re: Multiple subtyping with alias this and nested classes

2009-10-04 Thread Max Samukha
On Sat, 03 Oct 2009 16:30:11 -0600, Rainer Deyke rain...@eldwood.com
wrote:

Max Samukha wrote:
 The above sucks because we can't specify which nameCollision gets
 implemented by which mixin. In current D, nameCollision of both
 interfaces is implemented by Flipper.

I don't think that being able to define multiple separate functions with
the same name and the same signature is a necessary feature of multiple
inheritance, or even a particularly well thought-out one.

It is not always a question of choice. For example, when you are not
the designer of base types you want to subtype.

Python is an example of a language without this feature, and multiple 
inheritance
is very common in Python.

One of the reasons Python's MI is not recommended is its reliance on
naming conventions. There is a note in some Python (version unknown)
docs:

It is clear that indiscriminate use of multiple inheritance is a
maintenance nightmare, given the reliance in Python on conventions to
avoid accidental name conflicts.
(http://www.python.org/doc/1.5.1p1/tut/multiple.html)


Re: Multiple subtyping with alias this and nested classes

2009-10-04 Thread Max Samukha
On Sat, 03 Oct 2009 21:19:05 +0300, Max Samukha spam...@d-coding.com
wrote:

We would probably be able to overcome the limitation if and when
explicit interface instantiation is implemented:


should be explicit interface implementation is supported. Sorry.




Re: Multiple subtyping with alias this and nested classes

2009-10-04 Thread Max Samukha
On Sun, 04 Oct 2009 00:10:30 +0200, Yigal Chripun yigal...@gmail.com
wrote:


class FlippingBlipper : IBlipper, IFilpper
{
 mixin Flipper F;
 mixin Blipper B;
 alias F.nameCollision nameCollision;
}


The problem is that IBlipper.nameCollision is totally unrelated 
to IFlipper.nameCollision (for example, if the interfaces/mixins come
from third-party libraries, whose developers don't know or care
about each other, e.g. Tango/Phobos :P). That's why either
nameCollision must have its own implementation.

In current D:

auto fb = new FlippingBlipper;
IFlipper f = fb;
IBlipper b = fb;
f.nameCollision;
b.nameCollision;

Both calls are dispatched to the same implementation (the one provided
by Flipper template), which is incorrect and undesirable.

I wonder if the following would work:

class FlippingBlipper : IBlipper, IFilpper
{
 mixin Flipper IFilpper;
 mixin Blipper IBlipper;
}



I don't think so.


Re: Multiple subtyping with alias this and nested classes

2009-10-04 Thread Yigal Chripun
Max Samukha Wrote:

 On Sun, 04 Oct 2009 00:10:30 +0200, Yigal Chripun yigal...@gmail.com
 wrote:
 
 
 class FlippingBlipper : IBlipper, IFilpper
 {
  mixin Flipper F;
  mixin Blipper B;
  alias F.nameCollision nameCollision;
 }
 
 
 The problem is that IBlipper.nameCollision is totally unrelated 
 to IFlipper.nameCollision (for example, if the interfaces/mixins come
 from third-party libraries, whose developers don't know or care
 about each other, e.g. Tango/Phobos :P). That's why either
 nameCollision must have its own implementation.
 
 In current D:
 
 auto fb = new FlippingBlipper;
 IFlipper f = fb;
 IBlipper b = fb;
 f.nameCollision;
 b.nameCollision;
 
 Both calls are dispatched to the same implementation (the one provided
 by Flipper template), which is incorrect and undesirable.
 
 I wonder if the following would work:
 
 class FlippingBlipper : IBlipper, IFilpper
 {
  mixin Flipper IFilpper;
  mixin Blipper IBlipper;
 }
 
 
 
 I don't think so.

I see. What you want is non-virtual MI. 
I don't think that allowing the derived class to have two distinct 
implementations for the same function prototype is a good idea. 
Eiffel handles this by giving the programmer controls to select features and 
rename them in the derived class which I think is better. 

// hypothetical syntax example
class FlippingBlipper : IBlipper, IFilpper {
 mixin Flipper F;
 mixin Blipper B;
 // rename the inherited interface functions 
 alias IBlipper.nameCollision boo;
 alias IFilpper.nameCollision foo;
// implement the now two distinct functions
   void foo() { F.nameCollision(); }
   void boo() { B.nameCollision(); }
}

you can further subtype and the derived foo  boo will override the respective 
interfaces. 



Re: Multiple subtyping with alias this and nested classes

2009-10-04 Thread Max Samukha
On Sun, 04 Oct 2009 06:31:25 -0400, Yigal Chripun yigal...@gmail.com
wrote:

Max Samukha Wrote:

 On Sun, 04 Oct 2009 00:10:30 +0200, Yigal Chripun yigal...@gmail.com
 wrote:
 
 
 class FlippingBlipper : IBlipper, IFilpper
 {
  mixin Flipper F;
  mixin Blipper B;
  alias F.nameCollision nameCollision;
 }
 
 
 The problem is that IBlipper.nameCollision is totally unrelated 
 to IFlipper.nameCollision (for example, if the interfaces/mixins come
 from third-party libraries, whose developers don't know or care
 about each other, e.g. Tango/Phobos :P). That's why either
 nameCollision must have its own implementation.
 
 In current D:
 
 auto fb = new FlippingBlipper;
 IFlipper f = fb;
 IBlipper b = fb;
 f.nameCollision;
 b.nameCollision;
 
 Both calls are dispatched to the same implementation (the one provided
 by Flipper template), which is incorrect and undesirable.
 
 I wonder if the following would work:
 
 class FlippingBlipper : IBlipper, IFilpper
 {
  mixin Flipper IFilpper;
  mixin Blipper IBlipper;
 }
 
 
 
 I don't think so.

I see. What you want is non-virtual MI. 
I don't think that allowing the derived class to have two distinct 
implementations for the same function prototype is a good idea. 
Eiffel handles this by giving the programmer controls to select features and 
rename them in the derived class which I think is better. 

// hypothetical syntax example
class FlippingBlipper : IBlipper, IFilpper {
 mixin Flipper F;
 mixin Blipper B;
 // rename the inherited interface functions 
 alias IBlipper.nameCollision boo;
 alias IFilpper.nameCollision foo;
// implement the now two distinct functions
   void foo() { F.nameCollision(); }
   void boo() { B.nameCollision(); }
}

you can further subtype and the derived foo  boo will override the respective 
interfaces. 

Yes, but what if nameCollision is a virtual function called somewhere
in the template mixin? Your example has effectively removed the
virtuality.

If your mixin template contains unimplemented or partially implemented
virtual functions (for example, in case of an abstract base type), you
have to derive another class to (re)implement them.

Ok, I'm not arguing that mixins+interfaces cannot be used to emulate
multiple subtyping. I'm arguing it has problems that may force one to
resort to horrible hacks.

How is it better than the solution provided by 'alias this' and nested
classes? 'alias this' doesn't require mixin templates, handles name
conflicts nicely, allows subtyping of value types, allows
(re)implementing base functions directly in the subtype (using nested
classes). 

BTW, your example rewriten with 'alias this' looks cleaner, IMHO:

class Flipper { ... }
class Blipper { ... }

class FlippingBlipper {
 Flipper flipper;
 Blipper blipper;
 
 this { blipper = new Blipper; flipper = new Flipper; }

 alias this flipper;
 alias this blipper;

 void foo() { blipper.nameCollision; } 
 void bar() { flipper.nameCollision; }
}

No interfaces, no templates, no renaming. Problem solved. Almost. We
have to be able to instantiate classes in-place to avoid unnecessary
allocations.


Re: Multiple subtyping with alias this and nested classes

2009-10-04 Thread Max Samukha
On Sun, 04 Oct 2009 15:26:53 +0300, Max Samukha spam...@d-coding.com
wrote:

BTW, your example rewriten with 'alias this' looks cleaner, IMHO:

class Flipper { ... }
class Blipper { ... }

class FlippingBlipper {
 Flipper flipper;
 Blipper blipper;
 
 this { blipper = new Blipper; flipper = new Flipper; }

 alias this flipper;
 alias this blipper;

 void foo() { blipper.nameCollision; } 
 void bar() { flipper.nameCollision; }
}

Even cleaner:

class FlippingBlipper : Flipper {
 Blipper blipper;

 this { blipper = new Blipper; }

 alias this blipper;

 void foo() { blipper.nameCollision; } 
 void bar() { nameCollision; } // will it call
Flipper.nameCollision?
}


Re: Multiple subtyping with alias this and nested classes

2009-10-04 Thread Sergey Gromov
Sun, 04 Oct 2009 00:10:30 +0200, Yigal Chripun wrote:

  interface IBlipper
  {
  void blip();
  void nameCollision();
  }
  template Blipper()
  {
  void blip() {}
  void nameCollision() {}
  }
 
  interface IFlipper
  {
  void flip();
   void nameCollision();
  }
  template Flipper()
  {
  void flip() {}
  void nameCollision() {}
  }
 
 interfaces implement virtual MI, so FlippingBlipper must implement one 
 nameCollision which is shared by both interfaces.

That's not correct if you're talking about virtual MI in C++.  There,
you'd have to create a common root for the virtual inheritance to
actually work:

class INameCollider
{
public:
virtual void nameCollision() = 0;
};

class IFlipper: public virtual INameCollider
{
public:
virtual void flip() = 0;
};

class IBlipper: public virtual INameCollider
{
public:
virtual void blip() = 0;
};

class FlippingBlipper: public IFlipper, public IBlipper
{
public:
// Contains single, common nameCollision()
virtual void nameCollision() {}
virtual void flip() {}
virtual void blip() {}
};

Otherwise, if IFlipper and IBlipper are unrelated, you have two separate
nameCollision() functions which you must disambiguate as
IFlipper::nameCollision() and IBlipper::nameCollision() both when
defining and when calling via a FlippingBlipper instance.


Re: Multiple subtyping with alias this and nested classes

2009-10-04 Thread Yigal Chripun
Max Samukha Wrote:
 
 I see. What you want is non-virtual MI. 
 I don't think that allowing the derived class to have two distinct 
 implementations for the same function prototype is a good idea. 
 Eiffel handles this by giving the programmer controls to select features and 
 rename them in the derived class which I think is better. 
 
 // hypothetical syntax example
 class FlippingBlipper : IBlipper, IFilpper {
  mixin Flipper F;
  mixin Blipper B;
  // rename the inherited interface functions 
  alias IBlipper.nameCollision boo;
  alias IFilpper.nameCollision foo;
 // implement the now two distinct functions
void foo() { F.nameCollision(); }
void boo() { B.nameCollision(); }
 }
 
 you can further subtype and the derived foo  boo will override the 
 respective interfaces. 
 
 Yes, but what if nameCollision is a virtual function called somewhere
 in the template mixin? Your example has effectively removed the
 virtuality.
 

it doesn't remove virtuality. Virtual functions are stored as pointers in the 
vtable. with my suggested solution the idea is that the same pointer in the 
vtable gets a new name in the derived class. 
when you mixin the template into the derived class the compiler would  resolve 
nameCollision to the new name foo because of the renaming rule in the derived 
class. 


 If your mixin template contains unimplemented or partially implemented
 virtual functions (for example, in case of an abstract base type), you
 have to derive another class to (re)implement them.
 
 Ok, I'm not arguing that mixins+interfaces cannot be used to emulate
 multiple subtyping. I'm arguing it has problems that may force one to
 resort to horrible hacks.
 
 How is it better than the solution provided by 'alias this' and nested
 classes? 'alias this' doesn't require mixin templates, handles name
 conflicts nicely, allows subtyping of value types, allows
 (re)implementing base functions directly in the subtype (using nested
 classes). 
 

I don't think I want non virtual MI in D since it is more trouble than it's 
worth. but *if* we discuss this, I think my suggested semantics are simpler. 
The syntax probably can be much better but that's a secondary issue IMO.

 BTW, your example rewriten with 'alias this' looks cleaner, IMHO:
 
 class Flipper { ... }
 class Blipper { ... }
 
 class FlippingBlipper {
  Flipper flipper;
  Blipper blipper;
  
  this { blipper = new Blipper; flipper = new Flipper; }
 
  alias this flipper;
  alias this blipper;
 
  void foo() { blipper.nameCollision; } 
  void bar() { flipper.nameCollision; }
 }
 
 No interfaces, no templates, no renaming. Problem solved. Almost. We
 have to be able to instantiate classes in-place to avoid unnecessary
 allocations.

with my design: 
class Foo : FlippingBlipper {
 override foo ...
 override bar ...
} 
IFlipper obj = new Foo; 
obj.nameCollision; // will call Foo.bar 

I don't think that's possible with your design.

besides, alias this is a hack. a better mechanism would be to have compile-time 
inheritance, IMO.



Re: Multiple subtyping with alias this and nested classes

2009-10-03 Thread Leandro Lucarella
Andrei Alexandrescu, el  2 de octubre a las 19:10 me escribiste:
 Leandro Lucarella wrote:
 We might have very different taste, but I find that a little... horrible.
 What do you have against mixins? I think you're trying to use D as C++ :)
 
 If mixins work better, all the better. How would you use them to
 achieve multiple inheritance?

Don't design with multiple inheritance in mind, use interfaces + mixins
for common functionality instead.

-- 
Leandro Lucarella (AKA luca)  http://llucax.com.ar/
--
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
--
Bermú con papafritas y good show!


Re: Multiple subtyping with alias this and nested classes

2009-10-03 Thread Andrei Alexandrescu

Leandro Lucarella wrote:

Andrei Alexandrescu, el  2 de octubre a las 19:10 me escribiste:

Leandro Lucarella wrote:

We might have very different taste, but I find that a little... horrible.
What do you have against mixins? I think you're trying to use D as C++ :)

If mixins work better, all the better. How would you use them to
achieve multiple inheritance?


Don't design with multiple inheritance in mind, use interfaces + mixins
for common functionality instead.


But you're just saying it. I think you'd agree I wouldn't just follow 
that dogma noncritically just because you told me what to do.


I don't think many people design with multiple inheritance in mind. They 
design aiming at a good design. In my experience, some designs can make 
gainful use of multiple inheritance of classes, and some of my best 
designs do use multiple inheritance simply because it was the best tool 
for the job. Scala supports that with mixins, D supports that with 
multiple subtyping.



Andrei



Re: Multiple subtyping with alias this and nested classes

2009-10-03 Thread Leandro Lucarella
Andrei Alexandrescu, el  3 de octubre a las 11:23 me escribiste:
 Leandro Lucarella wrote:
 Andrei Alexandrescu, el  2 de octubre a las 19:10 me escribiste:
 Leandro Lucarella wrote:
 We might have very different taste, but I find that a little... horrible.
 What do you have against mixins? I think you're trying to use D as C++ :)
 If mixins work better, all the better. How would you use them to
 achieve multiple inheritance?
 
 Don't design with multiple inheritance in mind, use interfaces + mixins
 for common functionality instead.
 
 But you're just saying it. I think you'd agree I wouldn't just
 follow that dogma noncritically just because you told me what to do.

No, because the language is designed to do that AFAIK, so it will be much
easier and clear (for who writes the code and who reads it). I think you
hack with alias this is more obscure (we might be hitting personal taste
here, I grant you that).

 I don't think many people design with multiple inheritance in mind.
 They design aiming at a good design.

But you always have to take into account the tools you have when
designing. What's the point of designing a perfect bridge assuming you
have a material that doesn't exist?

Of course you can do that, but when you hit reality, you'll have to hack
your design to fit your real tools. So you can design something that
looks like multiple-inheritance, because it's easier (or nicer) to do
so. But when you want to put that in reality, you have to choose what tool
to use. In C++ you probably want to use MI (because the language has
a good support for it), but in D you probably want to use interfaces
+ mixins (because the language has good support for it).

Of course you can even implement it in C, or even assembly; you can
implement it as in C in C++ or D too, but it would be harder and more
obscure.

 In my experience, some designs can make gainful use of multiple
 inheritance of classes, and some of my best designs do use multiple
 inheritance simply because it was the best tool for the job.

Sure, the problem comes when the language don't support MI ;)

So, there we are, you have D, which doesn't support MI per se, you have to
hack it. You can do it with the nested-inherited-classes+alias-this hack,
or by using interfaces+mixins. We agree at least that you have the same
result with both right? Then, I guess is just a matter of taste. I simply
find much more obscure and complex the nested-inherited-classes+alias-this
hack than interfaces+mixins :)

 Scala supports that with mixins, D supports that with multiple
 subtyping.

I don't know what you mean about multiple subtyping.

-- 
Leandro Lucarella (AKA luca)  http://llucax.com.ar/
--
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
--
I am so psychosomatic it makes me sick just thinking about it!
-- George Constanza


Re: Multiple subtyping with alias this and nested classes

2009-10-03 Thread Andrei Alexandrescu

Leandro Lucarella wrote:

Andrei Alexandrescu, el  3 de octubre a las 11:23 me escribiste:

Leandro Lucarella wrote:

Andrei Alexandrescu, el  2 de octubre a las 19:10 me escribiste:

Leandro Lucarella wrote:

We might have very different taste, but I find that a little... horrible.
What do you have against mixins? I think you're trying to use D as C++ :)

If mixins work better, all the better. How would you use them to
achieve multiple inheritance?

Don't design with multiple inheritance in mind, use interfaces + mixins
for common functionality instead.

But you're just saying it. I think you'd agree I wouldn't just
follow that dogma noncritically just because you told me what to do.


No, because the language is designed to do that AFAIK, so it will be much
easier and clear (for who writes the code and who reads it). I think you
hack with alias this is more obscure (we might be hitting personal taste
here, I grant you that).


Alias this was introduced purposedly to allow multiple subtyping. Until 
yesterday, however, I hadn't realized how much nested classes help with 
that. Even before that I wasn't worried, since MI designs are not as 
frequent as SI designs.



I don't think many people design with multiple inheritance in mind.
They design aiming at a good design.


But you always have to take into account the tools you have when
designing. What's the point of designing a perfect bridge assuming you
have a material that doesn't exist?

Of course you can do that, but when you hit reality, you'll have to hack
your design to fit your real tools. So you can design something that
looks like multiple-inheritance, because it's easier (or nicer) to do
so. But when you want to put that in reality, you have to choose what tool
to use. In C++ you probably want to use MI (because the language has
a good support for it), but in D you probably want to use interfaces
+ mixins (because the language has good support for it).

Of course you can even implement it in C, or even assembly; you can
implement it as in C in C++ or D too, but it would be harder and more
obscure.


In my experience, some designs can make gainful use of multiple
inheritance of classes, and some of my best designs do use multiple
inheritance simply because it was the best tool for the job.


Sure, the problem comes when the language don't support MI ;)

So, there we are, you have D, which doesn't support MI per se, you have to
hack it. You can do it with the nested-inherited-classes+alias-this hack,
or by using interfaces+mixins. We agree at least that you have the same
result with both right? Then, I guess is just a matter of taste. I simply
find much more obscure and complex the nested-inherited-classes+alias-this
hack than interfaces+mixins :)


I don't see using a nested class (or any class) with alias this as a 
hack. It's the way the whole thing is supposed to work in the first place.



Scala supports that with mixins, D supports that with multiple
subtyping.


I don't know what you mean about multiple subtyping.


You subtype once by using inheritance, and then some more by using alias 
this.



Andrei


Re: Multiple subtyping with alias this and nested classes

2009-10-03 Thread Leandro Lucarella
Andrei Alexandrescu, el  3 de octubre a las 12:03 me escribiste:
 So, there we are, you have D, which doesn't support MI per se, you have to
 hack it. You can do it with the nested-inherited-classes+alias-this hack,
 or by using interfaces+mixins. We agree at least that you have the same
 result with both right? Then, I guess is just a matter of taste. I simply
 find much more obscure and complex the nested-inherited-classes+alias-this
 hack than interfaces+mixins :)
 
 I don't see using a nested class (or any class) with alias this as a
 hack. It's the way the whole thing is supposed to work in the first
 place.

Ok, then, I just find it ugly and unnecessary since you can do the same
with interfaces+mixins. It's just a matter of personal preferences (as
I said in my first mail), there is no point on arguing about it. =)

-- 
Leandro Lucarella (AKA luca)  http://llucax.com.ar/
--
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
--
I'll take a quiet life,
a handshake of carbon monoxide,
with no alarms and no surprises,
no alarms and no surprises.


Re: Multiple subtyping with alias this and nested classes

2009-10-03 Thread language_fan
On Sat, 03 Oct 2009 13:52:51 -0300, Leandro Lucarella wrote:

 Scala supports that with mixins, D supports that with multiple
 subtyping.
 
 I don't know what you mean about multiple subtyping.

I have also not seen the specs for this feature. How does multiple 
subtyping work exactly in D? Does it have exactly the same semantics as 
using interfaces + mixing in the traits? Why was the 'alias foo this' 
chosen if you are also planning to add support for Scala like traits 
(some other thread here recently discussed this). Andrei, you probably 
know how Scala chooses the overrides and overloads when traits have 
conflicts. How does D handle this?


Re: Multiple subtyping with alias this and nested classes

2009-10-03 Thread Max Samukha
On Sat, 3 Oct 2009 14:11:37 -0300, Leandro Lucarella
llu...@gmail.com wrote:


Ok, then, I just find it ugly and unnecessary since you can do the same
with interfaces+mixins.

Actually, you can't. Consider:

interface IBlipper
{
   void blip();
   void nameCollision();
}
template Blipper()
{
   void blip() {}
   void nameCollision() {}
}

interface IFlipper
{
   void flip();
void nameCollision();
}
template Flipper()
{
   void flip() {}
   void nameCollision() {}
}

class FlippingBlipper : IBlipper, IFilpper
{
   mixin Flipper;
   mixin Blipper;
}

The above sucks because we can't specify which nameCollision gets
implemented by which mixin. In current D, nameCollision of both
interfaces is implemented by Flipper.

We would probably be able to overcome the limitation if and when
explicit interface instantiation is implemented:

template Blipper()
{
   void IBlipper.blip() {}
   void IBlipper.nameCollision() {}
}

template Flipper()
{
   void IFlipper.flip() {}
   void IFlipper.nameCollision() {}
}

Until then, mixin + interface just doesn't work.

It's just a matter of personal preferences (as
I said in my first mail), there is no point on arguing about it. =)


Re: Multiple subtyping with alias this and nested classes

2009-10-03 Thread Andrei Alexandrescu

language_fan wrote:

On Sat, 03 Oct 2009 13:52:51 -0300, Leandro Lucarella wrote:


Scala supports that with mixins, D supports that with multiple
subtyping.

I don't know what you mean about multiple subtyping.


I have also not seen the specs for this feature. How does multiple 
subtyping work exactly in D?


The feature is very much in the works. I gave a basic example for two 
types. Unfortunately at the moment only one alias this declaration is 
allowed. The plan is to allow any number.


Does it have exactly the same semantics as 
using interfaces + mixing in the traits?


No.

Why was the 'alias foo this' 
chosen if you are also planning to add support for Scala like traits 
(some other thread here recently discussed this).


Currently there are no plans to add support for Scala-like traits.

Andrei, you probably 
know how Scala chooses the overrides and overloads when traits have 
conflicts. How does D handle this?


Walter and I are working the kinks of name lookup. If you have ideas, 
please share.



Andrei


Re: Multiple subtyping with alias this and nested classes

2009-10-03 Thread Andrei Alexandrescu

language_fan wrote:

On Sat, 03 Oct 2009 13:52:51 -0300, Leandro Lucarella wrote:


Scala supports that with mixins, D supports that with multiple
subtyping.

I don't know what you mean about multiple subtyping.


I have also not seen the specs for this feature. How does multiple 
subtyping work exactly in D?


The feature is very much in the works. I gave a basic example for two
types. Unfortunately at the moment only one alias this declaration is
allowed. The plan is to allow any number.

Does it have exactly the same semantics as 
using interfaces + mixing in the traits?


No.

Why was the 'alias foo this' 
chosen if you are also planning to add support for Scala like traits 
(some other thread here recently discussed this).


Currently there are no plans to add support for Scala-like traits.

Andrei, you probably 
know how Scala chooses the overrides and overloads when traits have 
conflicts. How does D handle this?


Walter and I are working the kinks of name lookup. If you have ideas,
please share.


Andrei


Re: Multiple subtyping with alias this and nested classes

2009-10-03 Thread Yigal Chripun

On 03/10/2009 20:19, Max Samukha wrote:

On Sat, 3 Oct 2009 14:11:37 -0300, Leandro Lucarella
llu...@gmail.com  wrote:



Ok, then, I just find it ugly and unnecessary since you can do the same
with interfaces+mixins.


Actually, you can't. Consider:

interface IBlipper
{
void blip();
void nameCollision();
}
template Blipper()
{
void blip() {}
void nameCollision() {}
}

interface IFlipper
{
void flip();
 void nameCollision();
}
template Flipper()
{
void flip() {}
void nameCollision() {}
}

class FlippingBlipper : IBlipper, IFilpper
{
mixin Flipper;
mixin Blipper;
}

The above sucks because we can't specify which nameCollision gets
implemented by which mixin. In current D, nameCollision of both
interfaces is implemented by Flipper.

We would probably be able to overcome the limitation if and when
explicit interface instantiation is implemented:

template Blipper()
{
void IBlipper.blip() {}
void IBlipper.nameCollision() {}
}

template Flipper()
{
void IFlipper.flip() {}
void IFlipper.nameCollision() {}
}

Until then, mixin + interface just doesn't work.


It's just a matter of personal preferences (as
I said in my first mail), there is no point on arguing about it. =)


interfaces implement virtual MI, so FlippingBlipper must implement one 
nameCollision which is shared by both interfaces. however you can give 
names to mixins so that you could choose which implementation to use for 
that and also have both implementations.


class FlippingBlipper : IBlipper, IFilpper
{
mixin Flipper F;
mixin Blipper B;
alias F.nameCollision nameCollision;
}

I wonder if the following would work:

class FlippingBlipper : IBlipper, IFilpper
{
mixin Flipper IFilpper;
mixin Blipper IBlipper;
}





Re: Multiple subtyping with alias this and nested classes

2009-10-03 Thread Rainer Deyke
Max Samukha wrote:
 The above sucks because we can't specify which nameCollision gets
 implemented by which mixin. In current D, nameCollision of both
 interfaces is implemented by Flipper.

I don't think that being able to define multiple separate functions with
the same name and the same signature is a necessary feature of multiple
inheritance, or even a particularly well thought-out one.  Python is an
example of a language without this feature, and multiple inheritance
is very common in Python.


-- 
Rainer Deyke - rain...@eldwood.com


Multiple subtyping with alias this and nested classes

2009-10-02 Thread Andrei Alexandrescu
I just realized that nested classes work so well with alias this, you'd 
think it was an evil plot all along. It wasn't, but I'm happy about the 
coincidence.


Here's how to effect multiple subtyping in D very effectively:

import std.stdio;

class Base1 {
void fun() { writeln(Base.fun); }
}

class Base2 {
void gun() { writeln(Base.fun); }
}

class Multiple : Base1 {
// Override method in Base1
override void fun() { writeln(Multiple.fun); }
// Override method in Base2
class MyBase2 : Base2 {
override void gun() { writeln(Multiple.gun); }
}
// Effect multiple subtyping
Base2 _base2;
alias _base2 this;
this() {
_base2 = new MyBase2;
}
}

void main()
{
auto obj = new Multiple;
Base1 obj1 = obj;
obj1.fun();
Base2 obj2 = obj;
obj2.gun();
}

The program above segfaults because somehow obj2 is null. That is a bug 
I just reported. For now, you can replace obj2.gun() with obj.gun() to 
make things work.


When we first introduced alias this, I knew multiple subtyping was 
possible. I didn't expect it to dovetail so nicely with nested classes.



Andrei


Re: Multiple subtyping with alias this and nested classes

2009-10-02 Thread language_fan
Fri, 02 Oct 2009 13:00:05 -0500, Andrei Alexandrescu thusly wrote:

 I just realized that nested classes work so well with alias this, you'd
 think it was an evil plot all along. It wasn't, but I'm happy about the
 coincidence.
 
 Here's how to effect multiple subtyping in D very effectively:
 
 import std.stdio;
 
 class Base1 {
  void fun() { writeln(Base.fun); }
 }
 
 class Base2 {
  void gun() { writeln(Base.fun); }
 }
 
 class Multiple : Base1 {
  override void fun() { writeln(Multiple.fun); } 
  class MyBase2 : Base2 {
  override void gun() { writeln(Multiple.gun); }
  }
  // Effect multiple subtyping
  Base2 _base2;
  alias _base2 this;
  this() {
  _base2 = new MyBase2;
  }
 }

I do not get why didn't you just use the 'import' keyword here instead of 
alias, since what you are basically doing is importing the symbols from 
one scope to another. It would seem a perfect generalization of import to 
also include cases where 'with' is currently used and also alias. The use 
of the term 'alias' is somewhat confusing.


Re: Multiple subtyping with alias this and nested classes

2009-10-02 Thread Andrei Alexandrescu

language_fan wrote:

Fri, 02 Oct 2009 13:00:05 -0500, Andrei Alexandrescu thusly wrote:


I just realized that nested classes work so well with alias this, you'd
think it was an evil plot all along. It wasn't, but I'm happy about the
coincidence.

Here's how to effect multiple subtyping in D very effectively:

import std.stdio;

class Base1 {
 void fun() { writeln(Base.fun); }
}

class Base2 {
 void gun() { writeln(Base.fun); }
}

class Multiple : Base1 {
 override void fun() { writeln(Multiple.fun); } 
 class MyBase2 : Base2 {

 override void gun() { writeln(Multiple.gun); }
 }
 // Effect multiple subtyping
 Base2 _base2;
 alias _base2 this;
 this() {
 _base2 = new MyBase2;
 }
}


I do not get why didn't you just use the 'import' keyword here instead of 
alias, since what you are basically doing is importing the symbols from 
one scope to another. It would seem a perfect generalization of import to 
also include cases where 'with' is currently used and also alias. The use 
of the term 'alias' is somewhat confusing.


Well if we did use 'import' people would have asked why we don't use 
'alias' because that's much closer to what really happens.


Note that the feature does not only import symbols from one scope to 
another. It just allows you to substitute some expression when someone 
tries to use this under another type.



Andrei


Re: Multiple subtyping with alias this and nested classes

2009-10-02 Thread Max Samukha
On Fri, 02 Oct 2009 13:00:05 -0500, Andrei Alexandrescu
seewebsiteforem...@erdani.org wrote:

I just realized that nested classes work so well with alias this, you'd 
think it was an evil plot all along. It wasn't, but I'm happy about the 
coincidence.

Here's how to effect multiple subtyping in D very effectively:

import std.stdio;

class Base1 {
 void fun() { writeln(Base.fun); }
}

class Base2 {
 void gun() { writeln(Base.fun); }
}

class Multiple : Base1 {
 // Override method in Base1
 override void fun() { writeln(Multiple.fun); }
 // Override method in Base2
 class MyBase2 : Base2 {
 override void gun() { writeln(Multiple.gun); }
 }
 // Effect multiple subtyping
 Base2 _base2;
 alias _base2 this;
 this() {
 _base2 = new MyBase2;
 }
}

void main()
{
 auto obj = new Multiple;
 Base1 obj1 = obj;
 obj1.fun();
 Base2 obj2 = obj;
 obj2.gun();
}

The program above segfaults because somehow obj2 is null. That is a bug 
I just reported. For now, you can replace obj2.gun() with obj.gun() to 
make things work.

When we first introduced alias this, I knew multiple subtyping was 
possible. I didn't expect it to dovetail so nicely with nested classes.


Andrei

Neat! But what if there is Base3? Is it supposed to be subtyped like
this:

class Base3
{
 void run() {}
}

class Multiple : Base1 {
 // Override method in Base1
 override void fun() { writeln(Multiple.fun); }
 // Override method in Base2
 class MyBase2 : Base2 {
 class MyBase3 : Base3
 {
  override void run() { writeln(Multiple.run); }  
 }
MyBase3 _base3;
this() { _base3 = new MyBase3; } 
alias _base3 this;
  
 override void gun() { writeln(Multiple.gun); }
 }
 // Effect multiple subtyping
 MyBase2 _base2;
 alias _base2 this;
 this() {
 _base2 = new MyBase2;
 }
}
?

Note that there is an additional level of indirection per each
subtype:

auto m = new Multiple;

m.run is unrolled to m._base2._base3.run


Re: Multiple subtyping with alias this and nested classes

2009-10-02 Thread Max Samukha
On Fri, 02 Oct 2009 21:41:54 +0300, Max Samukha spam...@d-coding.com
wrote:


Note that there is an additional level of indirection per each
subtype:

subtype = subtyped type


Re: Multiple subtyping with alias this and nested classes

2009-10-02 Thread Andrei Alexandrescu

Max Samukha wrote:

On Fri, 02 Oct 2009 13:00:05 -0500, Andrei Alexandrescu
seewebsiteforem...@erdani.org wrote:

I just realized that nested classes work so well with alias this, you'd 
think it was an evil plot all along. It wasn't, but I'm happy about the 
coincidence.


Here's how to effect multiple subtyping in D very effectively:

import std.stdio;

class Base1 {
void fun() { writeln(Base.fun); }
}

class Base2 {
void gun() { writeln(Base.fun); }
}

class Multiple : Base1 {
// Override method in Base1
override void fun() { writeln(Multiple.fun); }
// Override method in Base2
class MyBase2 : Base2 {
override void gun() { writeln(Multiple.gun); }
}
// Effect multiple subtyping
Base2 _base2;
alias _base2 this;
this() {
_base2 = new MyBase2;
}
}

void main()
{
auto obj = new Multiple;
Base1 obj1 = obj;
obj1.fun();
Base2 obj2 = obj;
obj2.gun();
}

The program above segfaults because somehow obj2 is null. That is a bug 
I just reported. For now, you can replace obj2.gun() with obj.gun() to 
make things work.


When we first introduced alias this, I knew multiple subtyping was 
possible. I didn't expect it to dovetail so nicely with nested classes.



Andrei


Neat! But what if there is Base3? Is it supposed to be subtyped like
this:

class Base3
{
 void run() {}
}

class Multiple : Base1 {
 // Override method in Base1
 override void fun() { writeln(Multiple.fun); }
 // Override method in Base2
 class MyBase2 : Base2 {
 class MyBase3 : Base3
 {
  override void run() { writeln(Multiple.run); }  
 }

MyBase3 _base3;
this() { _base3 = new MyBase3; } 
alias _base3 this;
  
 override void gun() { writeln(Multiple.gun); }

 }
 // Effect multiple subtyping
 MyBase2 _base2;
 alias _base2 this;
 this() {
 _base2 = new MyBase2;
 }
}
?

Note that there is an additional level of indirection per each
subtype:

auto m = new Multiple;

m.run is unrolled to m._base2._base3.run


Multiple alias this declarations must be allowed.

Andrei


Re: Multiple subtyping with alias this and nested classes

2009-10-02 Thread Leandro Lucarella
Andrei Alexandrescu, el  2 de octubre a las 13:00 me escribiste:
 I just realized that nested classes work so well with alias this,
 you'd think it was an evil plot all along. It wasn't, but I'm happy
 about the coincidence.
 
 Here's how to effect multiple subtyping in D very effectively:
 
 import std.stdio;
 
 class Base1 {
 void fun() { writeln(Base.fun); }
 }
 
 class Base2 {
 void gun() { writeln(Base.fun); }
 }
 
 class Multiple : Base1 {
 // Override method in Base1
 override void fun() { writeln(Multiple.fun); }
 // Override method in Base2
 class MyBase2 : Base2 {
 override void gun() { writeln(Multiple.gun); }
 }
 // Effect multiple subtyping
 Base2 _base2;
 alias _base2 this;
 this() {
 _base2 = new MyBase2;
 }
 }
 
 void main()
 {
 auto obj = new Multiple;
 Base1 obj1 = obj;
 obj1.fun();
 Base2 obj2 = obj;
 obj2.gun();
 }
 
 The program above segfaults because somehow obj2 is null. That is a
 bug I just reported. For now, you can replace obj2.gun() with
 obj.gun() to make things work.
 
 When we first introduced alias this, I knew multiple subtyping was
 possible. I didn't expect it to dovetail so nicely with nested
 classes.

We might have very different taste, but I find that a little... horrible.
What do you have against mixins? I think you're trying to use D as C++ :)

-- 
Leandro Lucarella (AKA luca)  http://llucax.com.ar/
--
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
--
EL PRIMER MONITO DEL MILENIO...
-- Crónica TV


Re: Multiple subtyping with alias this and nested classes

2009-10-02 Thread language_fan
Fri, 02 Oct 2009 19:35:55 -0300, Leandro Lucarella thusly wrote:

 We might have very different taste, but I find that a little...
 horrible. What do you have against mixins? I think you're trying to use
 D as C++ :)

So basically the diamond problem is again implementable in D, yay?


Re: Multiple subtyping with alias this and nested classes

2009-10-02 Thread Andrei Alexandrescu

Leandro Lucarella wrote:

We might have very different taste, but I find that a little... horrible.
What do you have against mixins? I think you're trying to use D as C++ :)


If mixins work better, all the better. How would you use them to achieve 
multiple inheritance?


Andrei


Re: Multiple subtyping with alias this and nested classes

2009-10-02 Thread downs
language_fan wrote:
 Fri, 02 Oct 2009 19:35:55 -0300, Leandro Lucarella thusly wrote:
 
 We might have very different taste, but I find that a little...
 horrible. What do you have against mixins? I think you're trying to use
 D as C++ :)
 
 So basically the diamond problem is again implementable in D, yay?

Nah, there's no ambiguity - when in doubt, the primary inherited class is the 
source of the function.

AFAIK, alias this only kicks in on otherwise undefined functions.