Prev: C++/CLI limitations?
Next: SHA1
From: Sergey P. Derevyago on 7 Oct 2005 09:25 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 7 Oct 2005 09:52 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 7 Oct 2005 11:49 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 10 Oct 2005 07:11 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 13 Oct 2005 09:36
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! ] |