multiple inheritance

J

Jeff Louie

Please note that Eiffel is a .NET language that supports a form of MI.

Regards,
Jeff
 
J

Jon Skeet [C# MVP]

Jeff Louie said:
Please note that Eiffel is a .NET language that supports a form of MI.

Yes - but the way it does it is horrible. It bends .NET pretty badly
out of shape in order to achieve MI. In particular, clients in other
languages which try to use an Eiffel object which supposedly derives
from two classes won't see it that way (and can't, of course).

Full Kudos to the Eiffel team for getting the kludge to work, but it's
still a kludge.
 
G

Guest

Lebesque,

Thanks for your patience with the length of my response. Loved the
proposed approach which (for brevity) I'll call the PI (Pseudo
Inheritance) design technique. I recoded and experimented with this
approach this weekend.

Comparing 'PI' to 'MI' (after coding) my executive summary (short form)
of the differences as follows.

----------

1. Top level specification of state space in multiple inheritance

A. The PI design technique is a wrapper for functionality around
pre-existing state space.

B. MI allows (obviously) state and functional (static and dynamic) inheritance

C. The PI technique offered (by Lebesque) is a 'functional inheritance'
(dynamic component) high cost approach.

D. The approach fails if the inherited state space (static component) is
intrinsic to the target functionality.

2. Therefore - (e.g. Child_cls is Parent_cls and "kind of is" House_cls).

A. Dynamically true
B. Statically false

C. Which is a formal agreement of your phrase '(e.g. A is C and "kind of is"
B)'.

D. The 'kind of' is a logical marker for the PI non-inheritance of
functional state space.

----------

Since I use MI for 'top level specifications' (as above) my use of PI
would be as a 'functional wrapper'. As a 'functional wrapper' on
pre-existing state space its a good approach if all you needed was a small
wrapping functionality around a pre-existing state space.

I have a follow up to this (post) if it is of interest. It has your code
redone to prove the 2.A, 2.B assertions above. The proff also shows the
severe limitations of C# as a strategic migration tool to factor out common
code. It brings out in code the 'kind of' (see above) inheritance
architecture flaw in C#.

To restate: The re-write of your code shows the 'statically false' assertion
in your 'e.g' given in executive summary above. Sort of explains the above
executive summary in code.

Thanks for your thoughtful and insightful input. I haven't used this
approach but to overcome C# limitations (MI in IMHO ) this approach is
pretty handy :)

Shawnk

PS. Let me know if you want me to post the rewritten proof of your code.

PPS. High cost based on quantitative/qualitative metrics (1) character
count, (2) visual complexity of pass through code and (3) logical complexity
of pass through code.
 
G

Guest

Jon,

Do you think this (valiant but flawed) effort is indicative of;

1. Inherent Jitter architecture flaw/weakness
2. Inherent MSIL architecture flaw/weakness
3. Inherent Multilple Inheritance problem with Von Nueman (turing tape)
engines

Thanks as always for your insightful comments and input.

Shawnk
 
L

Lebesgue

Shawnk,

thanks for your input. I agree with your arguments and would be glad to
see the rewritten proof. If I did my estimation right, then I think I have a
proposal which will improve the design "towards shared state space".
Looking forward to hear from you

Lebesgue
 
G

Guest

Lebesque,

(IMHO)

The import of your PI technique to C# language architecture is the
potential for a 'low cost' functional wrapper on existing state space.
The 'wrapper' expression would allow a semantic pass through of all
'existing target' (the class being wrapped) functionality and state space.

The state space of the wrapper itself would not be accessible to the
target. It would be accessible, as coded, to the client.

The temporal data channel (return/parameter streams of target methods)
could be passed through.

The semi-persistent data facade (properties, fields) of the target could
be passed through.

I am not qualified to judge if this is good (or bad) without significant
efforts to compare to strategic C# design and alternative solutions. But
hopefully Anders and the dev team will look at this if they are already
not aware of the approach (which I suspect they are).

I DO think (hip shot) that the PI technique is an excellent way of
understanding the architectural partitioning of the state space.

I recast your code into role based artifacts as inheritance (parent/child)
and embedding (house/mansion) phenomena.

I really liked coding this approach and it helped me to better articulate
some of the key issues with MI vs Interface (state space specification at
the top level). Without shooting my self in the foot (hip shot astray) I
could see where this is a good solution to have in approaching the C# MI
inheritance flaw (IMHO).

Thanks so much for your input and the 'mud' article.

BTW - The 'ball of mud' paradigm is an eloquent articulation to explain
the use of MI as a strategic approach to long term functional migration
(away from a big ball of mud :)

Shawnk

PS. The rewrite of the code is below (I hope I copied it in right -
compiles and runs OK for me)

Key point : There is no instance of 'House' identity due to the lack
of instrinsic state space removed via the PI approach.

---------------------

public
class MS_example_03_dem_cls
{
Parent m_parent_ins;
Child m_child_ins;
House m_house_ins;
Mansion m_mansion_ins;

public
void Demo_MI_operator()
{
m_parent_ins = new Parent ( "Fred Flintstone" );
m_child_ins = new Child ( "Pebbles" );

// What we would like to do is MI for house with the identity
functionality (instance name)

m_house_ins = new House ( m_child_ins );
m_mansion_ins = new Mansion ( "Mansion" );

// House now contains 'resident' functionality of child/parent.
// All 'resident' function must be 'coded out' indivdually
// Incoming client requests are funnelled to the 'delegated functionality
resident in child'

m_parent_ins. Print_identity();
m_child_ins. Print_identity();

// See if house can behave like parent
//
// With MI we could just 'pass through' the child functionality to do
the following
// Also we could set the name of the house to 'House' for its correct
identity
//
// m_house_ins. Print_identity();
//
// With PI the code to 'pass through' the identity fucntion is the
Del..() method.
//

m_house_ins. Delegation_cost_Print_identity();

//
// With true inheritance we get a no cost 'pass through' of both state
and function
//

m_mansion_ins. Print_identity();

//
// This inheritance is an excellent mechanism for the stratigic migration
of common
// function (inclusive of state) toward a target base class library
//

}

} // End_of_class

class Parent
{
private string name;

public Parent( string identity)
{
name = identity;
}
public void Print_identity()
{
Console.WriteLine(" My identity is {0} ", name);
}
}

class Child : Parent
{
public Child (string identity ) : base ( identity )
{
}

public static implicit operator House(Child child)
{
return new House(child);
}
}

class House
{
private Child child;

public House(Child child)
{
this.child = child;
}
public void Delegation_cost_Print_identity()
{
child.Print_identity();
}
}

class Mansion : Child
{
public Mansion(string identity ) : base ( identity )
{
}
}
 
G

Guest

Lebesque,

In passing I guess the PI implementation (as C# expression artifact) would be
a 'pass through conversion operator'. The embedded entities in the 'house'
could
be decorated with an attribute (the pass through attribute) that would signal
the compiler to generate all valid (non-conflict) pass through requests of
the client.

The compiler would have to prevent any semantic collision (between house and
child) by ensuring no artifacts in the child were duplicated in the house.
(functional
separation to ensure the semantic synchronization of the 'pass through'
functional channel (set of artifacts being passed through).

Shawnk
 
J

Jon Skeet [C# MVP]

Shawnk said:
Do you think this (valiant but flawed) effort is indicative of;

1. Inherent Jitter architecture flaw/weakness
2. Inherent MSIL architecture flaw/weakness
3. Inherent Multilple Inheritance problem with Von Nueman (turing tape)
engines

I think it's the normal problem of trying to make a square peg fit in a
round hole. The framework has its own idioms, and Eiffel wants to
bypass those idioms.

Without *some* idioms/rules, the CLR would be too general to be useful,
IMO. However, no set of idioms/rules can accommodate every way of
approaching things.

In short, I don't think it's a flaw in anything particularly - you have
to accept that no framework is going to be perfect for every
programming paradigm.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top