On Tue, 12 Aug 2003, Yukihiro Matsumoto wrote:

> In message "differences between Module and Class ?"
>     on 03/08/11, Mathieu Bouchard <matju / sympatico.ca> writes:
> |So, is there anything I may be missing ?
> I don't think so.  You've covered as much as I know.

Thank you very much. Now I have one-half of a future RCR and I'm trying to
complete its other half. I'm trying to figure out the feasibility of
merging the Module class with the Class class, with all the consequent
changes, and with as much backward compatibility as possible. (If enough
compatibility is not possible, then I wouldn't approve my own proposal.)



Here are the main consequences I've found to that change:

1. Module==Class returns true, and so no longer Module<Class returns true.
   Therefore, Module#include would work with Class arguments
   and class A<x would work for any Module x.



2a. Class.new is moved to Object#new. A Class that does not have Object in
    its ancestor list does not inherit from Object#new and is thus
    uninstantiable.
  OR
2b. Class.new stays where it is. Former Modules thus become instantiable
    (though not necessarily meaningfully).



3. the "class" and "module" keywords would become equivalent. Maybe the
difference would be that the default for "class" is to inherit from Object,
and the default for "module" is to not inherit at all.



4. a Class can inherit from another Class. the inheriting Class may have
Object twice in its ancestors, but Ruby's ancestor lookup would eliminate
duplicates in the same way that non-Class Modules are when they are
duplicately #included according to the rules of the current system.



Here are problems and drawbacks and further consequences that I have yet
to solve:



1. what about difference #6 (from the previously submitted list) ?

>  6. if Class===B and Class===A and B<A, then also
> (class<<B;self;end)<(class<<A;self;end). This does not occur if A is a
> non-Class Module, nor in any other case.

a Class inheriting from another cause the corresponding metaclasses to
inherit from each other. This has an effect on "class methods". This thing
currently does not happen in non-Class Modules. I wonder whether there are
adverse consequences of making it happen in non-Class Modules. I have not
fully examined yet. This may be the only outstanding technical issue.



2. Pickaxe says "multiple inheritance [can be] dangerous, as the
inheritance hierarchy can become ambiguous. [Mixins] provide a controlled
multiple-inheritance-like capability with none of the drawbacks" (p.23).

Pickaxe was the first printed English book on Ruby, which for me was an
appropriate successor to ruby-man-1.4, and quite elegantly written.
However the part I've cited above is, after close examination, a wild,
bold opinion that I find very difficult to agree with. [if Pickaxe is not
the most used Ruby book anymore, I would like to know... I'm not on
ruby-talk anymore. Or is a 2nd edition coming?]

The drawbacks of multiple inheritance ("ambiguity") are handled in Ruby in
the following way: (a) Instance variables of an object are not stratified
according to which classes they are defined in, instead they are in one
big pool and it's the programmer's responsibility to manage them, rather
than the language's; (b) For methods in a given method-lookup, after an
ordered depth-first search of ancestors, the duplicate modules are
removed. That is how Ruby and LISP both solve the diamond-shaped
inheritance issue.

Mixins are not any more "controlled", in that everything you can do with
"real" multiple-inheritance (in LISP for example) can be also achieved in
Ruby, if one is willing to turn every Class into a Module, and to make a
dummy Class for each module so that this Module becomes instantiable.
Mixins are more "controlled" in the sense that you have rather arbitrary
restrictions that provide no advantage and have to be circumvented.

I assert that Ruby is essentially a multiple-inheritance language, but
with unnecessary complications, rather than a single-inheritance language
with an added cool-sounding feature.



3. While examining and discussing the possibilities, I have heard a few
curious things.

For example, that it's very important to have a mechanism to distinguish
instantiables and non-instantiables; however that is quite strange in a
language that stays very much away from more important (in the sense of:
commonly wished for) kinds of restrictions such as type-checking.

I have been told that if you have a grouping of constants, then it's more
"elegant" to make it a Module rather than a Class. That kind of elegance
is quite foreign to me, and so I'm quite puzzled as to what it means.
There has also been mention that Module is a "purely-namespacing
construct", but I could not get a satisfying explanation to what makes
non-Class Modules like that and Classes not like that, and I really mean
in Ruby, not using another language's definition for the word "module".

I have been told that "including a Module" sounds better than "inheriting
from a Class", and "it doesn't make sense to mixin a class", and "i like
modules being different from classes", and "i've never found it confusing
-- it always seemed very open and clear to me", and "I've always thought
of Modules as UMLish Interfaces that happen to be able to provide
implementation as well as defining an API.". (Alright. Modules are like
Interfaces, except that they define implementation, but of course they're
really not Classes, and that is so much better than just Classes with 
M.I.! How open and clear is that?)

I have been told "i'm actually intrigued by the idea of modules coming in
and out on the fly... which is one reason the 'module' idea appeals to me
more than MI just with classes". (What about adding superclasses on the
fly? What part of "backward-compatible merging of Module and Class" am
I being unclear on?)

For the most part I don't seem to have many supporters. I can see people
who say Modules are "very different" from Classes and that mixing-in is
not inheritance, but never really tried and examined the practical
differences, or else are dodging the "Why" question altogether. I can see
people who like to conceptually differentiate between Module and Class
although they know how it works. I see people who'd agree with me if
they'd see an advantage to removing the distinction. I see few who
directly agree with me (and I hope this mail changes the situation).



4. I have very recently been told, by one Ruby veteran, that I really have
a problem understanding Modules and Classes. I will not comment on that,
consider it an outlier, and will leave for others to judge my competence,
given my past record writing Ruby and writing about Ruby.



I would very much appreciate comments on this pre-proposal.

Have a good day and/or night.

________________________________________________________________
Mathieu Bouchard                       http://artengine.ca/matju