From: ram@eiffel.com (Raphael Manfredi)
Newsgroups: comp.lang.perl
Subject: Re: Package & Namespace Question
Summary: Every package needs to inherit from main
Keywords: package, inheritance, perl 5
Date: 19 Dec 92 01:40:12 GMT
Organization: Interactive Software Engineering, Santa Barbara CA

Quoting lwall@netlabs.com (Larry Wall) from comp.lang.perl:
>The primary motivation for nesting packages would be to provide inheritance
>of object methods, and I don't see the need offhand for every class to
>derive from package main.  If you've got a good reason to do so, now is
>the time to let me know.

I believe it is a desirable property to have all the classes (packages)
inherit from one root class (package main), since the root class is the
only possible repository for basic features which need to be seen by all
the user-defined classes.

Let me give you an example by using Eiffel terminology and syntax, since
Perl does not (yet) support OO constructs. Those of you who are not interested
in those considerations may skip to the next article (needless to say, since
if you came that far...).

So, in Eiffel 3, all the classes are implicitely inheriting from one class
called ANY, which means all the possible types in the system (a class is
both a module and a type in Eiffel) conform to ANY. (Eiffel purists will know
that I am an odious liar, since I am omitting class GENERAL, but this is not
comp.lang.eiffel).

This means that if you want to declare a fairly general data structure (say a
LINKED_LIST), you can declare:

	pool: LINKED_LIST [ANY];

(The [] denotes genericity, pool is a linked list whose items are instances
-- or heirs for that matter -- of ANY).

You will be able to put *any* object into that structure, since every class
is inheriting from ANY and therefore any object can be assigned to an
entity whose type is ANY (Eiffel is "strongly" typed).

The ANY class also defines some common feature, for instance the 'twin'
feature which, applied to an object, returns a shallow copy (a clone) of
that object. In Eiffel, it is declared (by association) as:

	twin: like Current is
			-- New object field-by-field identical to `Current'.
		do
			...
		ensure
			is_equal: Result.is_equal (Current);
		end;
	
(The ensure clause is the post-condition, and it makes it pretty obvious
what `twin' does -- Current is the instance on which twin is called, and
Result is the predefined entity used to hold the function result).

Declaring `twin' by association is actually useful, since a given class C,
inheriting from ANY implicitely, twin will be visible and will return something
like C, i.e. either a C or one of its heirs.

Some special classes may chose to *redefine* twin by explicitely inheriting
from ANY and redefining that feature, which means dynamic binding will
apply and select the right implementation. Indeed, some basic features may
be more efficiently implemented in heirs (class INTEGER comes to mind).

If INTEGER was not actually inherting from ANY, there would be no way for
this class to re-implement the basic `twin' facility, which for in integer
is really a delicate matter, since it is a basic type, and has "expanded"
semantic in Eiffel (implying a semantic of copy on attachement).

Ok, back to Perl.

I know Perl has no pretention of being a strong OO language, but still there
are some single concepts like inheritance which, taken to their limits, can
produce outstanding results. In particular, grouping common feature in a
global package from which all the package would inherit (e.g. exception
handling) would give a tremendous amout of flexibility.

Of course, simply inheriting is not enough. The ability to rename and also
redefine a single routine has to be given, along with automatic dynamic
binding (possibly optimized by the compiler as static binding if no
redefinition occurs -- that's better than having to explicitely request
for dynamic binding since this enhances reusability).

This also means that multiple inheritance must be supported to some extent,
and, possibly, repeated inheritance (i.e. inheriting more than once from one
particular package -- this can be direct or indirect via multiple inheritance).

Anyway, it all depends to what degree you want to support Object-Oriented
features. But a fair amount of generality is best, since it leaves the
door open to future extensions. So if it does not cost much to let
every package inherit from main, why not make it available. Further extensions
will come naturally.

Now, did I do a good job in convincing you?
-- 
Raphael Manfredi <ram@eiffel.com>
Interactive Software Engineering Inc.
270 Storke Road, Suite #7                      / Tel +1 (805) 685-1006 \
Goleta, California 93117, USA                  \ Fax +1 (805) 685-6869 /
Newsgroups: comp.lang.perl