Re: A Change In Terminology: Monomorphic Objects. Polymorphic Objects
Le Chaud Lapin wrote:
Happy New Years All,
I read in a concurrent post that the fad that "everything is an object"
is on the way out. That's probably good - I have seen designs where
the classes are actually nothing more than collections of functions
wrapped in something that just happens to have the word "class affixed
to it":
class MemoryScanner
{
virtual Scan (...)
// 20 virtual functions, many of which are global functions in
disguise
// 2 member variables.
} ;
class MemoryScannerBigMem : MemoryScanner
{
virtual Scan (...)
} ;
class MemoryScannerFactory()
{
MemoryScanner * GetMemoryScanner();
} ;
MemoryScannerFactory *pMemScannerFactory = new MemoryScannerFactory();
MemoryScanner pMemScan = pMemScannerFactory->GetMem..
Uggh...I get nauseous trying to finish even this small example. But
you get the point. Everything is verb-oriented. Many virtual
functions. Much new()'ing. Much delete()'ing. The mood when reading
the code is "do this, do that." It is almost as if the programmer is
allergic to state. In any case, this style of programming leads too
much getting, and doing, and verifying, and initializing....
Java pretending to be C++. It isn't surprising it looks nasty. Taking
the idioms of one language into another is always going to be pretty
horrid. Especially where those idioms are the result of the language
architecture rather than the system design.
I'm not averse to factories, I use them a lot, but never do they look
like those. Yeach indeed.
Occasionally, the thing that is being "got" is not well-formed (read,
the programmer has not figured out its true nature), so there is a
necessity to make it polymorphic. This in turn leads to other issues
such as lifetime management, etc.
There is a different style of programming that resists the
verb-oriented paradigm. It focuses instead on what things are instead
of what they do, on the principle that, if you know what it is, you
already know what it does. The above example rewritten would be:
class MemoryScanner
{
void Scan(...) ;
} ;
MemoryScanner scanner;
scanner.Scan(...);
Now this second form has no pointers involved, and there are no
ownership issues. You certainly do not "get" a memory scanner. You
"use" one that you make, on the stack. This is only possible, of
course,if the programmer exercises sufficient forethought to determine
the nature of that which is being objectified so that virtual functions
can be obviated. This, in turn, presumes that it is even possible that
a quasi-terminal form for the latter can be found. That is a matter of
another debate however.
I think somebody else mentioned PIMPL. In effect you've made the
MemoryScanner class the factory and everything happens behind the
scenes with this class forwarding to the correct implementation, or
you've worked out that you only need a single implementation by better
analysing the use and implementation of MemoryScanner. Either way it is
the business of the implementation of MemoryScanner and only its
business.
When I discuss the difference between these styles of programming to
other C++ programmers, I find myself at a loss for good terms. In my
mind, the second Scanner is just as much an object as the the first.
In fact, I would say that an object is a thing, and since a purely
abstract class cannot even be instantiated, then it could be regarded
as less of a thing than a concrete object.
The previous sentence hints at another problem. Technically, both these
classes are abstract. After all, that is what we do as coders: we
create suitable abstractions for real things, suitable to the point
where we felt we have captured enough information that a true 1-to-1
correspondence is not necessary (too many silicon atoms would be
required). But the first form is has an "abstract" type and the second
form, well, it has a classification that is not abstract.
It is simply a stand-alone object. Whole and complete in and of itself
(modulus the implementation, but being an object we don't care about
that other than when writing it).
Nevertheless, I do not agree that the second form is not
object-oriented programming. I think both are object oriented
programming. I feel that a more appropriate nomenclature would have
been to refer to the former as polymorphic programming and the latter
as monomorphic programming, while still keeping in mind the pro's and
con's of each.
Seems an artificial distinction to me. As you've already said they are
simply variations on a design and both are objects and both are equally
object oriented.
The problem with your "polymorphic programming" is that it again
stresses the wrong thing. The STL is based more around the concepts of
your "monomorphic programming" having lots of stand-alone classes, but
they happen to be implemented as templates. They are of course
polymorphic.
One problem is that polymorphism is extremely badly taught and most
programmers working in Java and C++ don't seem to understand the
different forms of polymorphisms. In Java its understandable as the
language only supports one form, but C++ is a lot more flexible.
I also speculate that some authors might have been overzealous in
preempting the anticipated tendency of future programmers to forsake
polymorphic programming by "using C++ as a better C". So they employed
the English language to make it clear that:
You are are not really an OO Programmer unless you use polymorphism.
You aren't an OO programmer unless you use polymorphism, but that isn't
the same as using inheritance. Javascript is OO and uses polymorphism
quite happily without needing inheritance. In Smalltalk the inheritance
is there only as a convenience to the programmer and it also manages
quite happily.
Polymorphism isn't inheritance. If it were that would be akin to saying
that std::list isn't polymorphic and that std::max isn't polymorphic.
...thus inducing anyone who would dare call himself/herself an OO
Programmer to begin using virtual functions as soon as possible. They
got what they asked for: virtual functions abound, and there is so much
polymorphism, one begins to wonder if something a little more concrete
is in order.
What shall we call the second type of programming? Concrete?
Monomophic? Dead?
Let's just call it OO, but try to teach OO a bit better.
The problem is the influence of Java as it is now seen as the canonical
OO language. The problem is that it uses a form of OO that is very
unnatural, and worse, crippled. Surprisingly Javascript is a much more
representative OO language than Java is. C++ is good, but there is a
regretable tendancy to follow Java idioms (and even worse C ones).
Smalltalk is good, but it is hard to convince anybody that it is a
practical language for real-world problems.
OO is really about message passing and message delivery mechanisms.
This is a far more subtle view and one that Java chose not to implement
in order to provide strong types and to cut out the perceived
complication of templates. The problem is that they've removed the main
form of polymorphism in OO (operational) and forced everything to use
inclusional polymorphism. It shouldn't be strange that people find this
extremely hard work.
Here is Alan Kay on what OO is about (The big idea is "messaging"):
http://lists.squeakfoundation.org/pipermail/squeak-dev/1998-October/017019.html
K
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]