July 13, 2012
On Fri, Jul 13, 2012 at 11:30 PM, Andrei Alexandrescu < SeeWebsiteForEmail@erdani.org> wrote:

> On 7/13/12 3:18 PM, Christophe Travert wrote:
>
>> Andrei Alexandrescu , dans le message (digitalmars.D:172280), a écrit :
>>
>>> For Fruit.Seed it's Fruit, for AppleSeed it's Apple. This makes sense
>>>> because the Apple, which AppleSeed sees is the same object, which Fruit.Seed sees as it's base type Fruit.
>>>>
>>>
>>> That would mean AppleSeed has two outer fields: a Fruit and an Apple.
>>>
>>
>> Only one. Apple. And when AppleSeed.super seed this Apple, it sees a fruit.
>>
>> AppleSeed a;
>> assert(is(typeof(a.outer) == Apple));
>> assert(is(typeof(a.super) == Seed));
>> assert(is(typeof(a.super.**outer) == Fruit));
>> //but:
>> assert(a.outer is a.super.outer);
>>
>> If you can't figure out how can a.outer and a.super.outer have two different types, but be the same, think about covariant return.
>>
>
> Makes sense, thanks.
>
> Andrei
>
>
The initial question was: why does DMD 2.059 reject this if this makes
sense?
It's not even a new feature. It's a (possibly) new (and apparently
sensible) use case of an existing feature.

I came up with this when I was trying to work around the limitation of not having multiple inheritance.

-- 
Bye,
Gor Gyolchanyan.


July 13, 2012
On 7/13/12 3:36 PM, Gor Gyolchanyan wrote:
> The initial question was: why does DMD 2.059 reject this if this makes
> sense?
> It's not even a new feature. It's a (possibly) new (and apparently
> sensible) use case of an existing feature.

I think the simple answer is there was no provision for it. The feature copies the Java feature, and I don't think Java has something like what you defined.

Andrei

July 13, 2012
On Fri, Jul 13, 2012 at 11:41 PM, Andrei Alexandrescu < SeeWebsiteForEmail@erdani.org> wrote:

> On 7/13/12 3:36 PM, Gor Gyolchanyan wrote:
>
>> The initial question was: why does DMD 2.059 reject this if this makes
>> sense?
>> It's not even a new feature. It's a (possibly) new (and apparently
>> sensible) use case of an existing feature.
>>
>
> I think the simple answer is there was no provision for it. The feature copies the Java feature, and I don't think Java has something like what you defined.
>
> Andrei
>
>
Well, the nested classes are pretty much useless without this feature. Except for translating Java code. If I had multiple inheritance, I'd just make the Apple as base class and have all the seeds virtually derive from it. Not having multiple inheritance drove me to try the next best think. And after it failed, I complained about it. And here we are. Is it a difficult thing to fix?

-- 
Bye,
Gor Gyolchanyan.


July 13, 2012
On Friday, 13 July 2012 at 19:35:34 UTC, Gor Gyolchanyan wrote:
>
> The seed can't be an interface because it needs to contain state. For instance the progress towards becoming the respective fruit.

 The interface itself may not have state, but what uses the interface can have state. So i don't see an issue. Worse case you can use an abstract class which is a partial definition.

interface Counter {
  void addOne();
  int getCount();
}

//A contains state and is both A and Counter.
class A : Counter {
  int x;
  void addOne() {x++;}
  void getCount() {return x;}
}

> The seed needs to be aware of the fruit it came from to access the fruit's DNA to inherit the traits of that fruit when it grows into a fruit of its own. (Please note, that it's just an example).

> A fruit can have multiple such seeds, each of which must have it's own state and connection to the same fruit they came from.

so far...
class Fruit {
 class Seed {
  class Apple {}
 }
}

>
> So, we start off by inheriting from Fruit, defining the properties of that fruit (It's an Apple, it's delicious and it goes great in a pie). Then we define several different types of Apple seeds, each of which need access to the apple.

Hmmm...
interface Seed {}

class Fruit {
  class Appleseed : Seed {
    class Apple {}
  }

  //or?
  static class Apple {
    class AppleSeed : Seed {} //multiple seeds, but need Fruit access?
  }
}

or perhaps...?

interface Seed{}
interface Fruit{}

//Apple knows it's a fruit..
class Apple : Fruit {
  //Appleseed is from the Apple (which is a fruit as well)
  //Appleseed is a seed, we can have multiple seeds from Apple, all which know
  //all about Apple's (and basic fruits) but not about non-appple seeds.
  class Appleseed : Seed {
  }
}
July 13, 2012
On Fri, Jul 13, 2012 at 11:59 PM, Era Scarecrow <rtcvb32@yahoo.com> wrote:

> On Friday, 13 July 2012 at 19:35:34 UTC, Gor Gyolchanyan wrote:
>
>>
>> The seed can't be an interface because it needs to contain state. For instance the progress towards becoming the respective fruit.
>>
>
>  The interface itself may not have state, but what uses the interface can
> have state. So i don't see an issue. Worse case you can use an abstract
> class which is a partial definition.
>
> interface Counter {
>   void addOne();
>   int getCount();
> }
>
> //A contains state and is both A and Counter.
> class A : Counter {
>   int x;
>   void addOne() {x++;}
>   void getCount() {return x;}
>
> }
>
>  The seed needs to be aware of the fruit it came from to access the
>> fruit's DNA to inherit the traits of that fruit when it grows into a fruit of its own. (Please note, that it's just an example).
>>
>
>  A fruit can have multiple such seeds, each of which must have it's own
>> state and connection to the same fruit they came from.
>>
>
> so far...
>
> class Fruit {
>  class Seed {
>   class Apple {}
>  }
> }
>
>
>> So, we start off by inheriting from Fruit, defining the properties of
>> that fruit (It's an Apple, it's delicious and it goes great in a pie). Then
>> we define several different types of Apple seeds, each of which need access
>> to the apple.
>>
>
> Hmmm...
> interface Seed {}
>
> class Fruit {
>   class Appleseed : Seed {
>     class Apple {}
>   }
>
>   //or?
>   static class Apple {
>     class AppleSeed : Seed {} //multiple seeds, but need Fruit access?
>   }
> }
>
> or perhaps...?
>
> interface Seed{}
> interface Fruit{}
>
> //Apple knows it's a fruit..
> class Apple : Fruit {
>   //Appleseed is from the Apple (which is a fruit as well)
>   //Appleseed is a seed, we can have multiple seeds from Apple, all which
> know
>   //all about Apple's (and basic fruits) but not about non-appple seeds.
>   class Appleseed : Seed {
>   }
> }
>

The seed itself must have private state, or else it would violate
encapsulation and require nasty mixins.
And as I said, fruit can't know about apple.

-- 
Bye,
Gor Gyolchanyan.


July 13, 2012
On 7/13/12 3:49 PM, Gor Gyolchanyan wrote:
> On Fri, Jul 13, 2012 at 11:41 PM, Andrei Alexandrescu
> <SeeWebsiteForEmail@erdani.org <mailto:SeeWebsiteForEmail@erdani.org>>
> wrote:
>
>     On 7/13/12 3:36 PM, Gor Gyolchanyan wrote:
>
>         The initial question was: why does DMD 2.059 reject this if this
>         makes
>         sense?
>         It's not even a new feature. It's a (possibly) new (and apparently
>         sensible) use case of an existing feature.
>
>
>     I think the simple answer is there was no provision for it. The
>     feature copies the Java feature, and I don't think Java has
>     something like what you defined.
>
>     Andrei
>
>
> Well, the nested classes are pretty much useless without this feature.
> Except for translating Java code. If I had multiple inheritance, I'd
> just make the Apple as base class and have all the seeds virtually
> derive from it. Not having multiple inheritance drove me to try the next
> best think. And after it failed, I complained about it.. And here we
> are. Is it a difficult thing to fix?

I don't know, you may want to submit an enhancement request.

Andrei

July 13, 2012
On Fri, 13 Jul 2012 13:59:54 -0400, Gor Gyolchanyan <gor.f.gyolchanyan@gmail.com> wrote:

> Doesn't this make sense?
>
> class Fruit
> {
>     class Seed { }
> }
>
> class Apple: Fruit
> {
>      class AppleSeed: Fruit.Seed { }
> }
>
> This means, that as Fruit.Seed needs access to enclosing Fruit, AppleSeed,
> being a Fruit.Seed will also have access to enclosing Fruit, which is Apple.
> DMD 0.259 has this to say:
>
> Error: class main.Apple.AppleSeed is nested within Apple, but super class
> Seed is nested within Fruit
>
> Which doesn't make sense, IMO. What do you guys think about this? Who makes
> more sense me or DMD 2.059?
>


This is what you are asking for:

class A {}

class B : A {}

class C
{
   A member;
}

class D : C
{
   override B member;
}

You can mimic it via:

class C
{
   protected A _member;
   @property inout(A) member() inout { return _member; }
}

class C : B
{
   override @property inout(B) member() inout { return cast(inout(B))_member; }
}

I have had many times where I had to do this workaround (with casting), or store extra references, but it would be nice to have this simply work depending on the type.  I don't think anyone considered doing this with outer, it certainly would be a valid feature.  I'd like to have the general feature as well.  Covariant fields...

-Steve
July 13, 2012
On Friday, 13 July 2012 at 20:04:43 UTC, Gor Gyolchanyan wrote:
> On Fri, Jul 13, 2012 at 11:59 PM, Era Scarecrow
>> or perhaps...?
>>
>> interface Seed{}
>> interface Fruit{}
>>
>> //Apple knows it's a fruit..
>> class Apple : Fruit {
>>   //Appleseed is from the Apple (which is a fruit as well)
>>   //Appleseed is a seed, we can have multiple seeds from Apple, all which
>> know
>>   //all about Apple's (and basic fruits) but not about non-appple seeds.
>>   class Appleseed : Seed {
>>   }
>> }
>>
>
> The seed itself must have private state, or else it would violate encapsulation and require nasty mixins.
> And as I said, fruit can't know about apple.

 Fruit doesn't know about apples in this last case, only that an apple IS a fruit (And can do anything a fruit can do). And the seed CAN have a private state, only part of the interface (from interface Seed) is exposed. So I do not see a problem.

 interface Seed {
   void func();
 }

 class Appleseed : Seed {
  int x; //private state
  void func() {x++;}
 }

 Appleseed a = new Appleseed();
 Seed s = cast(Seed) a;

 //appleseed
 a.func();
 a.x = 5;

 //seed
 s.func(); //known and callable
 s.x = 10; //error, x isn't defined or known in seed. How is this not private state?
July 14, 2012
On Sat, Jul 14, 2012 at 12:31 AM, Andrei Alexandrescu < SeeWebsiteForEmail@erdani.org> wrote:

> On 7/13/12 3:49 PM, Gor Gyolchanyan wrote:
>
>> On Fri, Jul 13, 2012 at 11:41 PM, Andrei Alexandrescu
>> <SeeWebsiteForEmail@erdani.org <mailto:SeeWebsiteForEmail@**erdani.org<SeeWebsiteForEmail@erdani.org>
>> >>
>>
>> wrote:
>>
>>     On 7/13/12 3:36 PM, Gor Gyolchanyan wrote:
>>
>>         The initial question was: why does DMD 2.059 reject this if this
>>         makes
>>         sense?
>>         It's not even a new feature. It's a (possibly) new (and apparently
>>         sensible) use case of an existing feature.
>>
>>
>>     I think the simple answer is there was no provision for it. The
>>     feature copies the Java feature, and I don't think Java has
>>     something like what you defined.
>>
>>     Andrei
>>
>>
>> Well, the nested classes are pretty much useless without this feature. Except for translating Java code. If I had multiple inheritance, I'd just make the Apple as base class and have all the seeds virtually derive from it. Not having multiple inheritance drove me to try the next best think. And after it failed, I complained about it.. And here we
>>
>> are. Is it a difficult thing to fix?
>>
>
> I don't know, you may want to submit an enhancement request.
>
> Andrei
>
>
http://d.puremagic.com/issues/show_bug.cgi?id=8389

Anyone who thinks this is important, please vote up.

-- 
Bye,
Gor Gyolchanyan.


July 14, 2012
On 07/13/12 21:41, Andrei Alexandrescu wrote:
> On 7/13/12 3:36 PM, Gor Gyolchanyan wrote:
>> The initial question was: why does DMD 2.059 reject this if this makes
>> sense?
>> It's not even a new feature. It's a (possibly) new (and apparently
>> sensible) use case of an existing feature.
> 
> I think the simple answer is there was no provision for it. The feature copies the Java feature, and I don't think Java has something like what you defined.
> 
> Andrei
> 

class Fruit {
    class Seed {
    }
}

class Apple extends Fruit {
    class AppleSeed extends Fruit.Seed {
        Apple getOuter() {
            return Apple.this;
        }
    }
}

class Main {
    public static void main(String[] args) {
        final Apple apple = new Apple();
        final Apple.AppleSeed appleSeed = apple.new AppleSeed();
        assert (appleSeed instanceof Fruit.Seed);
        assert (apple == appleSeed.getOuter());
        assert (appleSeed.getOuter() instanceof Apple);
        assert (appleSeed.getOuter() instanceof Fruit);
    }
}

This is valid Java code actually and I agree with Gor I would have expected it to work with D.

Guillaume