From: topmind on
Stefan Ram wrote:
> I was trying to write about the "advantages of
> object-oriented programming".
>
> Some other texts about this topic write sentences like
>
> - methods are kept with related data as one object
>
> - inheritance helps to reuse code
>
> But I did not wish to follow these lines, because I do not
> consider classes or inheritance to be a neccessary part of the
> definition of OOP.
>
> To me, this is the dispatch on the run-time type (run-time
> polymorphism).
>
> For the invocation
>
> f( x )
>
> , the method actually called depends on the run-time type of "x",
> while in a language that is not object-oriented it does not.
>
> Does this dispatch has advantages?
>
> In a object-oriented language, I write method definitions
> for each type (ignoring sub-types for simplicity):
>
> f( A x ) := 1. /* case 0 */
> f( B x ) := 2. /* case 0 */
>
> In a language that is not object-oriented, I'd write:
>
> f( x ) := run-time-type( x )== A ? 1 : 2. /* case 1 */
>
> So, why should the first notation be better than the
> second one?
>
> An attempt to answer this is: Now types (like »A«) can be
> handled more easily and independently. For example, to
> add/remove the type »A« from a library, one can simply
> add/remove the set of all methods with parameters of type »A«,
> otherwise one would need to edit the definitions of methods
> like in case 1.
>
> One can also group the method definitions within the source
> code and organize them by the types they are related to, for
> example: put all method definitions for a certain type into
> one file ("class"). Even with multimethods something similar
> is possible. With the coarse-grained method of case 1 this
> is not possible, because code for type A and type B is
> lumped together in one method definition.
>
> So in object-oriented programming, methods are more
> fine-grained (like in case 0), each method has a name and
> parameters and possibly documentation. Therefore, they can be
> organzied more easily and independently than larger methods as
> in case 1.
>
> Is this the most important advantage of run-time polymorphism
> / object-oriented programming?
>
> Are there other advantages?


Us OOP skeptics will point out that many things in the real world don't
divide up nicely into "sub-types". I feel that set-theory is a better
way to classify things in my domain than "types", and OOP offers no
native help for sets. Thus, I favor relational theory over OOP, even
though existing relational products are often lacking somewhat.

Also, the tight association between data and behavior that OOP assumes
is usually artificial in my experience.

-T-
oop.ismad.com

From: Mike Austin on
Just like clockwork. But anyway, what about we stray away from oop for a
second and get your thoughts on multiple-dispatch? An example in Dylan:

define method handle-event(object,
event :: <mouse-down>,
button == #left-button)
format-out("Left mouse button pressed\n");
end;

No need whatsoever for switch statements. Need to handle a new event? Write a
new method. Override a method but call the original? Call next-method().

I really wish that Dylan had succeeded. It's a beautiful language.


Mike
From: Patrick May on
ram(a)zedat.fu-berlin.de (Stefan Ram) writes:
> "topmind" <topmind(a)technologist.com> writes:
>>Us OOP skeptics will point out that many things in the real
>>world don't divide up nicely into "sub-types".

As an aside, Mr. Ram, you should probably read some additional
threads in which topmind(a)technologist.com participated. One I suggest
is:
http://groups.google.com/group/comp.object/browse_frm/thread/155a05e36c88c7fd/d329f71ec2033ae6?lnk=st&q=%22burden+of+proof%22+author%3Apjm%40spe.com&rnum=5#d329f71ec2033ae6
where he admits that he has so little experience with OO techniques
that he can't even remember the details of the one project where he
encountered them, he does not use OO in his daily work, and he is not
proficient in any OO language. I leave it to you to determine how
much weight to give to his opinions based on his 'experience'.

> I went to the Portland Pattern Repository, to find a huge page
> about the /disadvantages/ of OOP:
>
> http://c2.com/cgi/wiki?ArgumentsAgainstOop
>
> This also includes something similar to your argument
> regarding sets.
>
> However, I did not find a page
>
> http://c2.com/cgi/wiki?ArgumentsForOop
>
> Does the Portland Pattern Repository have a page about
> "why OOP is better" or "arguments in favor of OOP"?
>
> Is there really no argument /for/ OOP?

Some of the best explanations of the benefits of OO with respect
to dependency management are the papers by Robert Martin on the Object
Mentor website (http://www.objectmentor.com/publications).

Regards,

Patrick

------------------------------------------------------------------------
S P Engineering, Inc. | Large scale, mission-critical, distributed OO
| systems design and implementation.
pjm(a)spe.com | (C++, Java, Common Lisp, Jini, middleware, SOA)
From: Dmitry A. Kazakov on
On 22 Oct 2006 15:58:36 GMT, Stefan Ram wrote:

> I was trying to write about the "advantages of
> object-oriented programming".
>
> Some other texts about this topic write sentences like
>
> - methods are kept with related data as one object
>
> - inheritance helps to reuse code
>
> But I did not wish to follow these lines, because I do not
> consider classes or inheritance to be a neccessary part of the
> definition of OOP.

They are, because they determine the way polymorphic methods are later
decomposed in:

> To me, this is the dispatch on the run-time type (run-time
> polymorphism).
>
> For the invocation
>
> f( x )
>
> , the method actually called depends on the run-time type of "x",
> while in a language that is not object-oriented it does not.
>
> Does this dispatch has advantages?
>
> In a object-oriented language, I write method definitions
> for each type (ignoring sub-types for simplicity):
>
> f( A x ) := 1. /* case 0 */
> f( B x ) := 2. /* case 0 */
>
> In a language that is not object-oriented, I'd write:
>
> f( x ) := run-time-type( x )== A ? 1 : 2. /* case 1 */
>
> So, why should the first notation be better than the
> second one?
>
> An attempt to answer this is: Now types (like ?A?) can be
> handled more easily and independently. For example, to
> add/remove the type ?A? from a library, one can simply
> add/remove the set of all methods with parameters of type ?A?,
> otherwise one would need to edit the definitions of methods
> like in case 1.

It is not only add/remove. You might be unable to write f(x), because the
types are unknown at compile time. Formally, a jump table is equivalent to
some switch, but. Tables can be composed dynamically (upon library load),
while switches cannot be, in a compilable language. So the advantage of OO
is in making code compilable, where otherwise it would be only
interpretable. This technically means huge difference not only in
maintenance and safety, but also in performance.

> One can also group the method definitions within the source
> code and organize them by the types they are related to, for
> example: put all method definitions for a certain type into
> one file ("class"). Even with multimethods something similar
> is possible. With the coarse-grained method of case 1 this
> is not possible, because code for type A and type B is
> lumped together in one method definition.

Yes. The case 1 has to define the whole class. The case 0 defines a class
through its specific types (A and B), and leaves the environment to bring
(and verify!) pieces together.

> So in object-oriented programming, methods are more
> fine-grained (like in case 0), each method has a name and
> parameters and possibly documentation. Therefore, they can be
> organzied more easily and independently than larger methods as
> in case 1.
>
> Is this the most important advantage of run-time polymorphism
> / object-oriented programming?

Higher abstraction and reuse is an advantage of polymorphism, be it dynamic
or not.

> Are there other advantages?

Consider other forms of decomposition (of a polymorphic f)

1. Inheritance:

f( A x ) := 1. /* case 0 */
// Nothing for B, it inherits f from A

f( x ) := run-time-type( x )== A ? 1 : 1. /* case 1 */

2. Extension: (found in constructors, destructors and aggregates):

f( A x ) := 1. /* case 0 */
f( B x ) := 1. /* case 0 */
// B::f results in 2, because B::f is an extension of A::f

f(x) := run-time-type ( x )== A ? 1 : 1 + 1. /* case 1 */

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
From: H. S. Lahman on
Responding to Ram...

> I was trying to write about the "advantages of
> object-oriented programming".
>
> Some other texts about this topic write sentences like
>
> - methods are kept with related data as one object
>
> - inheritance helps to reuse code
>
> But I did not wish to follow these lines, because I do not
> consider classes or inheritance to be a neccessary part of the
> definition of OOP.

I agree that those characterizations don't have a lot to do with what
OOA/D/P is about. However, they are a lot closer than saying that
neither classes nor inheritance are part of the definition of the OO
paradigm.

Class systems are absolutely crucial to OOA/D because they provide the
level of abstraction for logical indivisibility, provide a basis for
problem space abstraction, and enable relationships whose participation
is the primary mechanism for limiting access to state variables in the
OO paradigm.

While inheritance is less important than class systems to the OO
paradigm, one still needs a suite of rules for resolving properties of
individual objects in a generalization/specialization relation. Since
inclusion polymorphism is one of the more important OO tools and it is
enabled by generalization, one can't really dismiss inheritance.

>
> To me, this is the dispatch on the run-time type (run-time
> polymorphism).
>
> For the invocation
>
> f( x )
>
> , the method actually called depends on the run-time type of "x",
> while in a language that is not object-oriented it does not.

I'm afraid I don't follow this. In C, FORTRAN, or whatever the type of
'x' must be consistent with the signature defined for 'f'. In this
respect the OOPLs use exactly the same conventions as procedural
languages; they just support a broader range of types.

OOPLs, though, do allow overload polymorphism by allowing different
signatures for the same method. That, however, is probably the least
important form of polymorphism that the OO paradigm provides. (It is
not even relevant to OOA/D because one deals with knowledge attributes
at a much higher level of abstraction.)

>
> Does this dispatch has advantages?
>
> In a object-oriented language, I write method definitions
> for each type (ignoring sub-types for simplicity):
>
> f( A x ) := 1. /* case 0 */
> f( B x ) := 2. /* case 0 */
>
> In a language that is not object-oriented, I'd write:
>
> f( x ) := run-time-type( x )== A ? 1 : 2. /* case 1 */
>
> So, why should the first notation be better than the
> second one?

Your OO example is overload polymorphism. Generally that form of
polymorphism is not available in most non-OO languages. One can emulate
it in a variant on ad hoc polymorphism in some scripting and other
specialized languages as you indicate. But in most languages one cannot
test the type of an argument.

The closest thing one normally has in general purpose languages is ad
hoc polymorphism where one tests the /value/ of the argument to dispatch
to a behavior. Ad hoc polymorphism is done exactly the same way in the
OO paradigm.

However, I think this is academic because...

> Is this the most important advantage of run-time polymorphism
> / object-oriented programming?

Overload and ad hoc polymorphism are of relatively minor importance in
the OO paradigm compared to inclusion and parametric polymorphism.
(Parametric polymorphism is the more general sense of modifying behavior
through parametric attribute data rather than the uniquely 3GL view of
type substitution via mechanisms like STL.)

Parametric polymorphism, through the use of specification objects, is
especially important to OOA development because it enables encoding
invariants while relegating detailed differences to attribute values.
That can drastically reduce overall code size and, consequently, improve
reliability.

Inclusion polymorphism is especially important to OOP development
because it is the primary tool for addressing the physical coupling
problems inherent in 3GLs through dependency management.


*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
hsl(a)pathfindermda.com
Pathfinder Solutions
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development". Email
info(a)pathfindermda.com for your copy.
Pathfinder is hiring:
http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH