From: Sergey P. Derevyago on
dave_abrahams wrote:
> > AFAIKS they could get this right from the beginning; there is no excuse.
> > In particular, in my own Java code I always separate Iterator next() and
> > Object getVal() operations.
>
> Not that one is needed, but certainly there is an excuse, even if you
> buy into the idea that it's a mistake to have two iterators delimit a
> range -- which I don't. Especially at the time the STL was designed,
> the desire to allow the highest performance dictated that pointers
> should be usable as iterators directly. The abstraction penalty that
> could be associated with stuffing pointers into some other class was
> unacceptable. There are other arguments for the STL iterator model,
> too.
>
Sorry, Dave, I don't blame STL. I'm not satisfied with _Java_ approach.
It's James who doesn't like STL iterators.

> > still holds: generics in Java discriminates against built-ins such as int or
> > double.
>
> Actually the problem may be deeper than just discriminating against
> built-ins. I'm a bit fuzzy on the details right now, but as explained
> to me, you can't implement any function such as max, swap, etc., that
> has covariant argument types, on top of a runtime polymorphic system,
> without compromising static type safety.
>
Sure, you can't implement perfect compile-time type safety at run-time. Some
hacks are possible, thought.
--
With all respect, Sergey. http://ders.angen.net/
mailto : ders at skeptik.net

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: kanze on
Sergey P. Derevyago wrote:
> kanze wrote:
> > Sergey P. Derevyago wrote:
> > > kanze wrote:
> > >> They do weaken the argument by combining incrementation
> > >> and access in a single function; this is a definite
> > >> mistake,
> > > [1]
> > >> and makes it very difficult to write mutating filtering
> > >> iterators. On the other hand, most of the time I've
> > >> wanted to mutate, I've been able to make do with a view
> > >> of the collection, rather than iterators. And of course,
> > >> the lack of type safety could hardly be called a feature;
> > > [2]
> > >> I did have one or two cases where it was convenient, but
> > >> in each case, a collection of a discriminant union
> > >> (missing in both languages) would have been an even
> > >> better solution.

> > > IMHO even these two fundamental drawbacks clearly overweight
> > > the gains.

> > Well, it obviously depends on what you are doing. The first
> > drawback is usually fairly simple to work around (unlike the
> > fact that you need two iterators).

> AFAIKS they could get this right from the beginning; there
> is no excuse. In particular, in my own Java code I always
> separate Iterator next() and Object getVal() operations.

I certainly agree there. The concept of iterator is not a new
one, and it wasn't new even when the Java collection classes (or
the STL, for that matter) were being invented. If you look at
the different iterator classes that were current in C++ in the
early nineties, you'll find that almost all (the most notable
exception was the USL classes) had three functions: current(),
isDone() and next(). The actual names varied, but it was
generally recognized that there were three important things you
could do with an iterator, and the only reasonable abstraction
was to provide three functions, one for each thing.

> > The second is a basic problem with the language, not the
> > library; globally, if I'm writing robust code, I definitly
> > prefer C++, regardless of the library issues. But my
> > statement only concerned the actual libraries.

> > With regards to [2], too, I've heard that it has been
> > corrected in the most recent versions of Java.

> Not, unfortunately. The famous Alex Stepanov's statement

> You can't write a generic max() in Java that takes two
> arguments of some type and has a return value of that same
> type. Inheritance and interfaces don't help. And if they
> cannot implement max or swap or linear search, what chances do
> they have to implement really complex stuff? These are my
> litmus tests: if a language allows me to implement max and
> swap and linear search generically - then it has some
> potential.

Well, I don't necessarily agree with that statement, but I don't
think it relevant to what is being discussed here: iterators.
>From what I hear, the latest versions of Java do have ways of
creating type safe iterators. And while I did not consider the
lack of type safety a flaw in the iterator design (they didn't
have a choice, given the language they were using), it certainly
is a serious practical drawback.

> still holds: generics in Java discriminates against
> built-ins such as int or double.

Java discriminates against them in general. I never could
figure out why -- if every thing is an object, you define the
expression a + b to mean a.add( b ) (which means that operator
overloading is automatically implied). And count on the
compiler to do the necessary optimization if the type of a and b
is just a wrapper for int. (Note that Smalltalk did this from
the beginning, and that Smalltalk compilers were actually doing
this optimization before Java was invented. So there's no
excuse there, either.)

--
James Kanze GABI Software
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Niklas Matthies on
On 2005-10-07 13:09, Sergey P. Derevyago wrote:
> Niklas Matthies wrote:
:
>> public static <T extends Comparable<T>> T max(T a, T b)
>> {
>> return a.compareTo(b) > 0 ? a : b;
>> }
:
> IMHO auto(un)boxing is nothing more than a dirty hack.

Not moreso than other implicit conversions.

> In particular, I see the performance and overloading problems (at
> least). Look,
>
> void f(Object o) {} // [1]
> void f(int i) {} // [2]
>
> f(max(1,2));
>
> What f() will be called?

The first; but arguably, if it makes a difference in functionality,
then the design (i.e. having these f() overloads) is questionable
anyway.

I won't deny that there are quirks like this (in a pure OO language,
int would be an object type in the first place--I'm not sure whether
this would make you happy), but they do not constitute a fundamental
impediment to having generic code that works quite well for the basic
types.

-- Niklas Matthies

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Sergey P. Derevyago on
Niklas Matthies wrote:
> >> public static <T extends Comparable<T>> T max(T a, T b)
> >> {
> >> return a.compareTo(b) > 0 ? a : b;
> >> }
> :
> > IMHO auto(un)boxing is nothing more than a dirty hack.
>
> Not moreso than other implicit conversions.
>
Yes, some implicit conversions are evil. But you are allowed _not_ to use
them in your C++ code. In Java you have no choice, though.

> > In particular, I see the performance and overloading problems (at
> > least). Look,
> >
> > void f(Object o) {} // [1]
> > void f(int i) {} // [2]
> >
> > f(max(1,2));
> >
> > What f() will be called?
>
> The first; but arguably, if it makes a difference in functionality,
> then the design (i.e. having these f() overloads) is questionable
> anyway.
>
I don't think so. STL code exploits overloading heavily and does it for good
reason.
--
With all respect, Sergey. http://ders.angen.net/
mailto : ders at skeptik.net

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Virtanen Antti on
On 2005-10-07, kanze <kanze(a)gabi-soft.fr> wrote:

>> still holds: generics in Java discriminates against
>> built-ins such as int or double.
>
> Java discriminates against them in general. I never could
> figure out why -- if every thing is an object, you define the
> expression a + b to mean a.add( b ) (which means that operator
> overloading is automatically implied). And count on the
> compiler to do the necessary optimization if the type of a and b
> is just a wrapper for int. (Note that Smalltalk did this from
> the beginning, and that Smalltalk compilers were actually doing
> this optimization before Java was invented. So there's no
> excuse there, either.)

I've been wondering the same thing. Original reason for the primitive
types was "performance", which is quite obvious. However, as you said,
Smalltalk had this already, so this sounds like an excuse.

I suppose there might be certain situations in which the autoconversion
couldn't be decided during compilation and in these situations runtime
decisions and conversions would present a significant performance
penalty. Reflection and dynamic class loading could lead to such
situations, though perhaps a bit artificial ones.

Deriving a class MyInteger from built-in class Integer could also
present a performance problem for arrays containing Integer-instances.
Array of primitive ints is clearly a continuous block of memory
containing 32-bit numbers while array of Integers should look like an
array of "real" objects where the objects could be either from the
MyInteger or Integer. Oops, no more easy and fast memory (de)allocation
with zero space overhead. Of course, this could be prevented by making
Integer a "final" class, but this might prevent some reasonable use of
Integer-class.

This is going quite offtopic, so perhaps better end it :) Anyway, C++
might some day have reflection and auto(un)boxing too or we might be
using a language very similar to C++ which has these :)

--
// Antti Virtanen -//- http://www.students.tut.fi/~virtanea -//- 050-4004278


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7
Prev: C++/CLI limitations?
Next: SHA1