Ara.T.Howard wrote:
> On Sat, 30 Jul 2005, Adam P. Jenkins wrote:
>> By your logic, C++ and Python don't have the diamond problem either. 
>> Both of
>> those languages have well defined ways in which the method to call is
>> chosen, which have to do with the order in which the programmer writes
>> things.  So from the compiler's point of view, there is never a diamond
>> problem, unless you had a language specification which didn't define any
>> rules for resolving the issue.  The "diamond problem" is a problem for
>> humans, who may not always remember, or take into account, the language's
>> rules for choosing which method to call, so in that sense Ruby's module
>> include feature introduces exactly the same "diamond problem" that 
>> multiple
>> inheritence introduces into other languages.
> 
> 
> all true - but only for methods.  the thing with inheritence is that state
> (instance vars) also get inherited.

<snipped explanation showing that state can't be multiply inherited in 
Ruby.>

 > so now we do have a simple kind of 'diamond inheritence' but no
 > 'diamond problem' in the ruby runtime since the ordering of module
 > inclusion, as written by the programmer, makes totally unambiguous
 > the search path of method calls.

But the fact is that the C++ standard explicitly and unambiguously 
defines the behavior for multiply inherited state as well.   So, I still 
say that, if you maintain that the fact that Ruby has a well defined way 
of resolving which method to call when multiple modules include the same 
method name means that Ruby doesn't have the diamond problem, then the 
same logic should apply to C++.  Since C++ has a well defined way of 
resolving which instance variable gets accessed at any point in the 
code, there is no diamond problem.

Personally I don't think the "diamond problem" shouldn't be called a 
problem just because there's a solution.  Multiple inheritance 
introduces the possibility that members with the same name can be 
inherited multiple times at the same level in the inheritance tree. 
This is a problem that must be resolved, and it is resolved in all the 
MI languages I've used.  Nevertheless, even though the compiler knows 
what to do, the programmer may still get unexpected behavior if they 
multiply inherit (or multiply include in Ruby), without being aware that 
they are including multiple versions of the same member.  Another way of 
putting it is, just because the behavior is unambiguous to the compiler, 
that doesn't mean it always seems unambiguous to the programmer.  In 
that regard, I do agree that by disallowing multiply-inherited state, 
Ruby makes its behavior easier for humans to keep straight in their 
heads.  But I don't agree with the claim in the Pickaxe book that Ruby's 
module include feature "provides a controlled multiple-inheritance-like 
capability with none of the drawbacks."

Adam