From: Maciej Sobczak on
On 7 Cze, 11:25, "Martin Krischik" <krisc...(a)users.sourceforge.net>
wrote:

> > Considering the performance aspect, the layout of variables within the
> > object is determined *statically*
[...]

> Interesting opinion. Say we have
[...]

You are right here, I got confused by the low-level implementation
details.
There must be a run-time component of the access method for instance
variables from virtually inherited classes. Mea culpa.

I will still take the opportunity to twist my mistake :-) - take it as
a proof that I have never explicitly used virtual inheritance in
professionally written code, even though I *have* used multiple
inheritance occasionally.
Guess what - the default mechanisms always worked as I intended - this
might be an indication that the whole problem is not nearly as
dramatic as you portray it.

In other words, I disagree with your statement that the behavior of C+
+ in this area should be different.

> > Again, that knowledge would not necessarily help them, as the use of
> > virtual inheritance is not automatically justified.
>
> Like the use if virtual destructors is not automaticly justified?

That's right.

> Only:  
> count in your source the amount virtual destructors vs. non virtual  
> destructors.

OK. Let's take something publicaly verifiable: the YAMI4 project,
which contains some amount of C++ code (analyzed header files):
- All destructors: 28
- Virtual ones : 6

Let's take the SOCI project for comparison:
- All destructors: 61
- Virtual ones : 20

It looks like virtual destructors amount for some 20-30% of all in my
code.

> Why is what you need most not default?

I find that what C++ offers in this area is what I need most of the
time.
Now I even have the scientific and statistical proof for this, as
before this discussion I did not even know the real numbers. :-)

I don't claim that my experiences are representative, but I will take
the risk to claim that if you need all or most of your destructors to
be virtual, then you are probably trying to write Java in C++.

Now, to bring this discussion at least a bit back on topic, I think
that Ada could offer similar mechanisms as C++. The reason is that the
object model in both languages is very similar and in both cases based
on value semantics. In particular, I find it a nuisance that
controlled types must be tagged.

--
Maciej Sobczak * http://www.inspirel.com

YAMI4 - Messaging Solution for Distributed Systems
http://www.inspirel.com/yami4
From: Dmitry A. Kazakov on
On Mon, 7 Jun 2010 05:17:16 -0700 (PDT), Maciej Sobczak wrote:

> In particular, I find it a nuisance that
> controlled types must be tagged.

Ditto, types where a class may root.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
From: Martin Krischik on
Am 07.06.2010, 14:17 Uhr, schrieb Maciej Sobczak
<see.my.homepage(a)gmail.com>:

> It looks like virtual destructors amount for some 20-30% of all in my
> code.

Now that is interesting. It means that most of your classes are final as
the java guys would say. While I have always written under the premises
that my classes might become child classes for something else.

BTW: you are aware that if the parent class uses a virtual destructor then
the child class does as well - even when not explicitly specified?

> then you are probably trying to write Java in C++.

I learned C++ before Java using IBM Open Class Library
«http://en.wikipedia.org/wiki/IBM_Open_Class». Probably more then anything
the OCL influenced my OO thinking. A string class with lazy copy, a great
collection class which (optionality) implemented the observer notifier
pattern, a database persistence object layer. Well and 90% of the classes
descending form IVBase. Guess what the V stands for.

There is a class overview here

http://www.warpspeed.com.au/cgi-bin/inf2html.cmd?..%5Chtml%5Cbook%5CIBMVACPP%5CCPPCLRF.INF

or here:

http://caligari.dartmouth.edu/doc/ibmcxx/en_US/doc/hgref.htm

And yes the OCL shares a lot with Java. The single base class for example,
or a toString method for every class, or the use of interfaces.

Martin

--
Martin Krischik
mailto://krischik(a)users.sourceforge.net
https://sourceforge.net/users/krischik
From: Luis Espinal on
In article <op.vdvcs3b5z25lew(a)macpro-eth1.krischik.com>, Martin Krischik says...
>
>Am 28.05.2010, 07:25 Uhr, schrieb Luis Espinal <Luis_member(a)newsguy.com>:
>
>> I don't think that is much of an issue. Mutability is. This is a big
>> issue for
>> Java as it has turned out. The commonly accepted best practice now is to
>> mark
>> variables and parameters as final unless you know before hand that you
>> want to
>> change them.
>
>Which only makes the reference to the variable un-mutable, not the
>content.

Yes. Absolutely and you are right. I think I should say that comment is wrt of
Java default behavior towards variable/parameter declarations vs Scala's. So,
what we are referring to here is not so much immutability of class instances
(which would be the ideal... see below), but immutability of values and
arguments within expressions (a practical concession given the limits of the
language).

The argument here is values that are immutable (either manually as in Java or by
default as in Scala) leads to writing code based (or mostly based) on
expressions. When done properly, it tends to be succinct and yet readable.

>That combined with language which can do only pass by reference
>for all complex types and a Clonable interface which was badly sorted out
>gives you a language where the protection a getter function should give
>you is just not there - unless you make it a habit to use «return x.clone
>()» [1].
>

It's not just Cloneable that we have to deal with. It's also when implementing
Serializable. Or forced to rely on automatic garbage collection without having
reliable finalizer methods. Not having the C++ equivalent of const member
functions and const return types can be quite hurtful, too.

>And if we are at it - setter functions should use «this.x = x.clone ()».
>Those who did Ada or C++ know that. In Ada setter and getter functions
>usually take a copy and in C++ setter and getter functions take a
>reference to a constant object. That is: not the reference is constant -
>the object itself is constant (un-mutable).
>

You are going to have forgive my C++/Ada peasantry since I haven't touched
either for more than a decade (since I left grad school.) Why exactly would we
want (in Java) to return a clone wrt to a setter/getter?

I could understand *that* in C++ wrt to implementing a getter for an entity "A"
that returns a modifiable copy/clone of "A". But in Java (where we have no
guarantees when an object is going to be reclaimed), we simply cannot do that.

By default, we have to assume that if a getter returns a reference to an
instance of a class that is not immutable (.ie. extensions of java.lang.Number
or String), then we have the ability to modify it (while still being part of the
enclosing class exposing the getter method.)

That's the default modus operandi. Anything else (returning a deep or shallow
clone, for instance) has to be explicitly documented.

As you pointed out, however, a good and valid criticism can be made on Java
regarding 1) passing everything by value and 2) working with object references
only. Without having the C++ equivalent of const member functions and const
return types, it is impossible to syntactically enforce immutability. We can
only do so in Java by convention and by structuring our classes as either
mutable and immutable (the later being Scala's route.)

>As it is most setter and getter functions in Java are placebos - they give
>you you the feeling to do it the proper OO way but you are don't!
>
>Martin
>
>[1] provided the class at hand implements the Clonable interface property
>and does indeed do full deep copy.

I'm not sure I follow here either. I'm saying this genuinely, and I'd be happy
to see your POV on this subject.

To me a chain of calls P.getQ.getR...X.getY.getZ is simply a chain of messages
from the caller to an given entity(Z) all the way through different contexts.
The accessed attribute can be very primitive or complex, mutable or immutable,
all that depending on the nature of the message and the nature of the receiving
entity. That is, its complexity (or lack thereof) is implementation-specific,
and thus hidden by these getter and setter methods.

Whether it is immutable or if it permits mutability of one or all of its
attributes, that's specific of the entity's public interfaces. I'd grant that it
will be better, more syntactic, finer grained way of controlling mutability, but
its presence is not necessarily required for object-orientation.


I won't argue, however, the sad fact a lot of people in Java don't understand
that, and they end up simulating goto-based programming with their poorly
constructed classes :)

- Luis Espinal. luis.espinal(a)gmail.com

ps... I'll add to the discussion that one thing we sorely miss in Java is the
ability to write nested functions as in Ada, Pascal and ALGOL. IMO they lead to
cleaner, more organized code.

From: Martin Krischik on
Am 07.06.2010, 20:30 Uhr, schrieb Luis Espinal <Luis_member(a)newsguy.com>:

> In article <op.vdvcs3b5z25lew(a)macpro-eth1.krischik.com>, Martin Krischik
> says...
> Not having the C++ equivalent of const member
> functions and const return types can be quite hurtful, too.

cost is a reserved word in Java. That's for future use as keyword. So is
goto ;-).

>
>> And if we are at it - setter functions should use «this.x = x.clone
>> ()».
>> Those who did Ada or C++ know that. In Ada setter and getter functions
>> usually take a copy and in C++ setter and getter functions take a
>> reference to a constant object. That is: not the reference is constant -
>> the object itself is constant (un-mutable).
>>
>
> You are going to have forgive my C++/Ada peasantry since I haven't
> touched
> either for more than a decade (since I left grad school.) Why exactly
> would we
> want (in Java) to return a clone wrt to a setter/getter?

I thing this example should explain it:

java.util.ArrayList evilChange = someInstance.getPreciousList ();

evilChange.clear();

O course retuning a const would protect just as good and render better
performance.

Having immutable object like java.lang.String helps as well.

> By default, we have to assume that if a getter returns a reference to an
> instance of a class that is not immutable (.ie. extensions of
> java.lang.Number
> or String), then we have the ability to modify it (while still being
> part of the
> enclosing class exposing the getter method.)

In Java. Most other OO languages see that differently. The OO principle is
the the internal state of a class can only be changed true a setter. If I
have a state called preciousList you should not be able to change
preciousList using getPreciousList(). You should do so be using
setPreciousList(), setPreciousList(int) or appendPreciousList().

Why? For example my class states are usually bound. If you get the list
and change it behind my back the observers are never notified of change.
The hole observer/notifier pattern collapses. And with it the
model/view/controller pattern. And eh voila what is shown in the view is
not what is stored data access object and a difficult to find bug in the
middle.

> That's the default modus operandi. Anything else (returning a deep or
> shallow clone, for instance) has to be explicitly documented.

This in my eye is turning a fault into a virtue.

> only do so in Java by convention and by structuring our classes as either
> mutable and immutable (the later being Scala's route.)

immutable data access objects?

>> As it is most setter and getter functions in Java are placebos - they
>> give
>> you you the feeling to do it the proper OO way but you are don't!

> I'm not sure I follow here either. I'm saying this genuinely, and I'd be
> happy to see your POV on this subject.
>
> To me a chain of calls P.getQ.getR...X.getY.getZ is simply a chain of
> messages
> from the caller to an given entity(Z) all the way through different
> contexts.

That's ok. What I argue is that the following should not be allowed:

P.getQ.setR(…)

It should be:

q = P.getQ
q.setR(…);
p.setQ(q);

And the simplest of all examples are bound properties (that's
observer/notifier pattern for non Java developers). If you do the first
then the observers of P are not notified. of the change to Q. I would not
be surprised if observer/notifier was considered an anti pattern in Java
[1]. That again would be turning a fault into a virtue. Observer /
Notifier worked marvellously great in the IBM open class (C++).

> ps... I'll add to the discussion that one thing we sorely miss in Java
> is the
> ability to write nested functions as in Ada, Pascal and ALGOL. IMO they
> lead to
> cleaner, more organized code.


int f ()
{
class c
{
int g ()
{

};
}

c i = new c();

return i.g();
}


just about as painful as using local packages to add static variables to
Ada procedures.

Martin

[1] Like the singleton pattern. I read the rationale why singleton is
considered an anti pattern and it was all about Java quirks which do not
apply to Ada or C++. Still the Java advocates cry “anti pattern”. For me
anti pattern need to be anti pattern in all (or at least most) programming
languages.

PS: I am doing my SCJD right now. I think the assignment has been
specificity designed to make you hate Java. Or maybe I should not have
chosen rmi over socket communication after all...

--
Martin Krischik
mailto://krischik(a)users.sourceforge.net
https://sourceforge.net/users/krischik