D modeling

CheeseWiz CheesyFritos at gmail.com
Tue Jul 2 18:27:32 UTC 2019


On Tuesday, 2 July 2019 at 14:36:04 UTC, Jesse Phillips wrote:
> On Tuesday, 2 July 2019 at 01:21:56 UTC, CheeseWiz wrote:
>>
>> There are 3 main problems:
>>
>> 1. Because we cannot use multiple inheritance, this makes the 
>> code extremely verbose. We must use interfaces and the syntax 
>> becomes unnecessarily verbose, but it does work ultimately. 
>> Model inheritance has no issues with the diamond problem. Only 
>> one branch will ever be used(either through the base model or, 
>> when overridden, through the derived model).
>
> I don't see where you used multiple inheritance. Turn 
> everything into concrete/abstract classes and you should be 
> fine.

I didn't, D doesn't support MI.

One has to inherit the base model and the derived model 
relationships, that is MI.

     interface iDog : iAnimal, ModelA.iAnimal
     {

     }

     class Animal : ModelA.Animal, iAnimal
     {
		 override iFood LikesWhichFood() { return 
cast(iFood)super.LikesWhichFood;
     }

ideally we could just do

class Dog : Animal, ModelA.Animal

and that is MI. It would simplify both models

>
>>
>> 2. We must override and alias members that ultimately do not 
>> need to be expressed. The compiler can figure it out if it 
>> understood what was being done.
>
> Are you referring to the "NotImplementedException" that 
> proliferate most poorly designed abstractions?

		alias Attack = Animal.Attack;	// Required by D
		void Attack(iAnimal who) { super.Attack(who); }


D gave me an error and said I must use the alias(first line), 
without I get an error about a missing override.

Error: class `Models.ModelB.Cat` use of 
`Models.ModelA.Animal.Attack(iAnimal who)` is hidden by `Cat`; 
use `alias Attack = Animal.Attack;` to introduce base class 
overload set


>>
>> 3. Oop contravariance breaks the model logic and mixes 
>> dependencies. It is a non-issue in modeling. In D it requires 
>> us to cast everywhere. This is the main issue. You can see the 
>> issue at work using IsItTasty functions. It's simple, 
>> Contravariance prevents us staying with the derived model, we 
>> have to use the base model(for return types, same applies to 
>> arguments with covariance). But when we are in a derived model 
>> we are in it, we are using everything in the derived model 
>> that belongs to it(and behind them is the base model, but we 
>> do not directly refer to the base model), at least that would 
>> be the plan.
>
>
> With D support for both covariance and contravariance, you 
> should be covered. You desired model behavior should just fall 
> into place.
>

Yes, it seems that with the proper overrides it works. It is 
quite verbose, it would be amazing if all this stuff could be 
automated. It all is boilerplate code and requires for every 
model and every component of the model.

> Could you throw up a working example as a gist? Might take a 
> hack at it.

The OP contains a working example. Adding the overrides does 
solve problem 3 and so it is possible to have model inheritance 
in D! That is good news(I suppose it should be obvious since it's 
just normal inheritance)!

Now the only goal is too make it simple to do. I imagine meta 
programming and mixin templates could solve this... Not sure 
though if one would need partial classes to make it work. (it 
would be ugly to also have to have a lot of mixin templates 
littered throughout)

The goal would be to create something as simple as

model A : B
{

    // Add whatever extensions one wants, all plumbing is taken 
care of.
}



More information about the Digitalmars-d mailing list