Fantastic Map specializations and GC reduction

I think that macros can sometimes be used to come to the same end. I understand that they are not the same.

[quote]I personally prefer not to have the language dumbed-down to the level of VB. Reflection is a difficult (well I don’t think so, but others do) part of the Java language too
[/quote]
I agree. Reflection is great, and dumbing down a language is (usually) a bummer. That said, I don’t mind much that Java doesn’t have multiple inheritance or operator overloading… I think C++ is really pushing it on the operator overloading for instance >>, << for stream I/O and shifting seemed to be a bit of a stretch, but I admit I’ve gotten used to it.

[quote]No. Have you heard of concepts before? They are the C++ template equivalent of a Java interface.
[/quote]
I know what you are talking about, but I’m not that familiar with using the term ‘concepts’ in that context. I always considered using an abstract base class as an ‘interface’ to be a more direct equivalent to java’s ‘interface’.

[quote]For example, the sort function defines the values of the iterator parameters to implement the LessThanComparable concept, which, roughly speaking, means that they must be able to compare to each other using the “<” operator.
[/quote]
But the “<” operator is really nothing more than the Java compareTo method… At least the difference is insignificant in the same way that ‘java generics are just a fancy way to cast’. So I’m missing the point… I just don’t see how ‘concepts’ are fundamentally different. They both appear to allow for generic programming… at least to some degree. I mean, how is not writing an operator< any different from not implmenting the comparable interface? I believe you when you say ‘concepts are more powerful’, but what is not clear is “How much? and Why?”

[quote]Java generics don’t enable anything whatsoever besides casting. That doesn’t help anybody implement generic algorithms or containers in any fashion. Hopefully you’re starting to see some of the differences here.
[/quote]
I’m afraid I’m not yet seeing the differences, as I think generics do help, BY elminating the casting. Just as any high level language helps by allowing me to not write everything in machine code. That’s ultimately all any language feature is doing for you, be it ‘concepts’, generics, templates, whatever…

[quote]Programs that use templates this way have been around for at least over five years. That’s over half of Java’s entire lifetime.
[/quote]
That wasn’t the point… programs that use templates for anything more than saving you what you could get with some tedious cut and paste have been, in my experience, hard to come by. I just don’t see functional languages being used much. Lisp has been around for ages, and I only know of one program in wide spread use (Emacs) that has anything to do with it. I’ve heard of Haskell, I think I read a bit about it, and came to the same conclusion… it hasn’t caught on, sure it is used, but for much less than 1% of the software development going on in the world. (another assuption, I know)

[quote]Perhaps you don’t keep up with C++ as much as you used to? For example, how many C++ journals do you read compared to Java journals? How many C++ newsgroups do you read as compared to Java newsgroups? It’s easy to fall behind.
[/quote]
Very true, I don’t keep up as much as I would like… that’s sort of what I’m trying to do here :slight_smile: - I figure I learn it faster if you shove it down my throat :). I’m just at the stage where I am trying to get used to proper use of C++ templates and Smart pointers and C++ resouce management in the face of C++ exceptions… they are all areas that I know I need to develope in. This thread is helping to open some other possiblities… I wish I had more time to practice this stuff… as I fear I have already fallen too far behind. I tried to get things moving in that direction at my last workplace, but the rest of the team were happy with something only slightly beyond C++ as a better C… our object oriented design was lacking… i got violent protests from the use of C++ templates… mainly because the tools made them so hard to debug! (Try setting a break point in a specific instantiation of a template… ugh!)

BTW… Thanks for Jace… I now remember checking it out quite awhile ago, and you reminding me of it here made me take another look… I just may have a good opportunity to use it in my next project. It looks quite cool.

Scott

Good article. I only had the Javadocs on Proxy to glean my understanding from (and using them in practice doesn’t always reveal how things are done under the covers). Based on the article, you are correct that a byte[] is being generated and processed by a ClassLoader when a Proxy is being generated. Unfortunately, some things are left unclear.

I coudln’t find ‘Listing 5’ to see what the decompiled Proxy does. Obviously I can’t argue that bytecodes aren’t being generated, but without seeing what Listing 5 is, I’d like to propose that the bytecodes generated are more ‘metadata’ then implementation code (I’m wondering what resembelance to the decompiled proxy file would look vs a decompiled interface file). My comparision between STL and Proxy generation is (and I still am not sure that my assumption is wrong) is that in the case of STL, the code within the template is duplicated, if I had a sprintf(“Hello world”) in my template, the binary code that tells the OS to output “Hello World” would be duplicated once in each instance of the template type (If no, why would I need to re-build the generated classes to get the new changes?). In the case of the proxy, the are bytecodes that I have in my InvocationHandler being used for every proxy instance I create to implement the proxy, or is the invocation handler being copied into the new proxy that was generated? Is the implementation of the Proxy forced to create a byte[] of bytecode because, currently, that’s the only way to interface with the class loader to build a Class at runtime? Does anyone else feel that by embedding the bytecode specification into the API, that if the bytecode spec changes they need to remember to not only update the compilers (javac) but also go back to this one class and update it so that it generates proper bytecode? I liked the separation between the API and bytecode but now it just got tighter-coupled. Hopefully they will introduce in the future an API to dynamically define classes through method invocation instead of writing a raw bytestream and loading it into the class loader. Seems like a kludge.

Get over it.

Nice attitude. Another possible response could have been ‘If proxy generation involved building a class through an API and not producing bytecode that is processed by a ClassLoader, it might apply, but that’s not what has been shown to be the case.’ For someone who concludes with ‘God bless’ after every post, you certainly have a remarkable lack of consideration for another person’s point of view.

-Chris

Ok, found listing 5, and the bytecode generated creates a big wrapper. I can see why the author of the article wasn’t impressed by the proxy. I don’t really see the InvocationHandler code being generated in the generated Proxy0.class tho, unless I’m reading too deeply into your comparison between Proxy and STL…I got the impression that I should have no problem with what STLs are doing because Proxies are doing the same thing…and, again, my problem with STL is the copy-paste coding style not so much as a ‘code generator’ like the Proxy is…I’m not sure why you brought it up…is this what you call a ‘straw man’?

-Chris

I think that macros can sometimes be used to come to the same end. I understand that they are not the same.

Macros can be used to do all sorts of things, for example, you can implement inheritance, reflection, and serialization with macros. That doesn’t mean that macros are more than shallowly related to first class implementations of those mechanisms.

That said, I don’t mind much that Java doesn’t have multiple inheritance or operator overloading…

Java does have multiple inheritance - It’s just multiple interface inheritance. I’ve found multiple implementation inheritance can be useful (for example, it gets used in Jace to make java::lang::Throwable both a std::exception and a java::lang::Object), but I rarely use it.

I think C++ is really pushing it on the operator overloading for instance >>, << for stream I/O and shifting seemed to be a bit of a stretch, but I admit I’ve gotten used to it.

Operator overloading is nice, but it’s abused terribly. Outside of mathematic code, I find that operators are powerful in that they allow primitives to be treated polymorphically along with other class types in templates. That’s incredibly useful.

Of course all of these things are peripheral to the primary discussion - Java generics and templates.

I know what you are talking about, but I’m not that familiar with using the term ‘concepts’ in that context. I always considered using an abstract base class as an ‘interface’ to be a more direct equivalent to java’s ‘interface’…

You dance all around the point here. Yes, a pure abstract C++ class is the direct equivalent of a Java interface. However, I stated that a concept is the C++ template equivalent of a Java interface. Java has no direct analog for a concept. Templates implement compile-time polymorphism and operate on structural conformance. A concept describes compile time structural conformance. An interface describes run time named conformance.

But the “<” operator is really nothing more than the Java compareTo method…

Yes, my point last time was that concepts are indeed used like Java interfaces. I was trying to explain that the LessThanComparable concept was roughly equivalent to the Comparable interface. The larger goal was to correct the misunderstanding that C++ template specializations were somehow related to Java interfaces.

I just don’t see how ‘concepts’ are fundamentally different.

Like I said, concepts operate on structural conformance, which is more powerful. It’s what allows for cool things like traits and policy classes and non-virtual polymorphism in general. But again, that’s not the main point. The main point was correcting the misunderstanding concerning specialization.

I think generics do help, BY elminating the casting.

I’m not arguing that eliminating casting is bad, just like I wouldn’t argue that retrieving the name of a class at runtime is bad. However, if that was the only capability reflection had, you’d be seeing me ranting about how much reflection sucks.

That wasn’t the point… programs that use templates for anything more than saving you what you could get with some tedious cut and paste have been, in my experience, hard to come by.

Okay, first, Java generics aren’t powerful enough to even save you from lots of cut and paste. Repeat with me, Java generics only add casts.

Second, even if you don’t personally write code that makes use of advanced template features, you use the Standard C++ Library, which makes use of them.

Outside of that, I believe the C++ code you work with is probably heavily biased (correct me if I’m wrong).

I’m just at the stage where I am trying to get used to proper use of C++ templates and Smart pointers and C++ resouce management in the face of C++ exceptions…

Right, you are more concerned about basic C++ coding than advanced use of C++. That shouldn’t prevent other programmers from making use of powerful C++ techniques. If you were just at the stage of learning how to properly prevent object leaks in your Java code, would you want to prevent someone else from using anonymous inner classes?

I tried to get things moving in that direction at my last workplace…

I’m sorry to hear that’s the environment you work in. I have recently had to work with people who have a hard time using C++ even as a better C.

i got violent protests from the use of C++ templates… mainly because the tools made them so hard to debug! (Try setting a break point in a specific instantiation of a template… ugh!)

Humm… In VC++ you can set a breakpoint in any particular instantiation of a template. Just set the breakpoint in your template definition, Hit Alt+F9 (Edit->Breakpoints) and breakpoints for all of the different instantiations of that template will be set. You can remove the ones you’re not interested in. I have seen where this doesn’t show up correctly until you make a trial run through your code.

BTW… Thanks for Jace… I just may have a good opportunity to use it in my next project.

I hope it can help you out. Any suggestions you have are welcome.

God bless,
-Toby Reyelts

Did you mean remove casts? And doesn’t generics give you compile time type safety of collections (Like I can’t add a String to a Vector without generating an error at compile time) on top of the fact that i don’t need to do something like (Integer)v.get(key) (where generics remove the need for casting). I’m a big fan of find out problems at compile time. I can understand that Templates in general have evolved into a very powerful tool, it sounds like it supports lots of features such as AOP, Concepts, etc, in addition to parameterized types, I think the scope of Generics is much much smaller (only support parameterized types). If the overall theme is that you want Java to do more, better, I don’t think anyone would say they didn’t want that too. Perhaps the label ‘Generics’ placed on the parameterized type functionality is stretching the term too much based on your C++ background, but from my perspective, I see it fulfilling a specific need. I wish I had more background in in the other aspects that are being described here, but I don’t, so I can only argue why it’s good enough for me.

-Chris

[quote]Operator overloading is nice, but it’s abused terribly. …operators … allow primitives to be treated polymorphically along with other class types in templates. That’s incredibly useful.
[/quote]
I agree completely.

[quote]You dance all around the point here.
[/quote]
Sorry, about that… but it’s because I’m just not seeing it clearly. The things you describe, ‘concepts’, and uses in STL for instance, don’t seem to be using those advanced concepts in a way that is unique enough that Java doesn’t have a facility for doing the same thing with similar effort (with generics). STL generic algorithms and container classes (the bulk of my experiece with STL, if I’m missing something big let me know) can all be implemented in Java with generics and interfaces… or so it would appear. So I’m missing where the ‘advanced’ C++ templates are coming into play. So far the examples of computing a factorial, or unrolling loops are all I have. Useful for sure, but not enough (for me) to rant over.

[quote]non-virtual polymorphism
[/quote]
This sounds like the bit I’m missing… perhaps I really need to learn more about what that really means… as my Java examples with interfaces are ‘virtual polymorphism’

[quote]Right, you are more concerned about basic C++ coding than advanced use of C++. That shouldn’t prevent other programmers from making use of powerful C++ techniques.
[/quote]
Absolutely true, but I also don’t want the language polluted with fancy tricks that just give programmers enough rope to hang themselves. Because not having to deal with that stuff is part of what I like about Java.

[quote]In VC++ you can set a breakpoint in any particular instantiation of a template.
[/quote]
Ah, but I was doing device driver work, and SoftIce and templates didn’t get along so well… Shoot, I had arguments just with respect to moving to C++ for kernel mode drivers. I would have hated to lose that one :).

Another problem was the horrible error messages that the compiler spewed forth when something very simple was wrong with template based code… Trying to figure out the actual location of the error was quite a pain. I’m hoping that VC 7 and other compilers are getting better at that.

Sorry, about that… but it’s because I’m just not seeing it clearly…

Oh well, I’ve tried my best to explain them in a few short posts, but I obviously do not seem to be doing a good job. We can always discuss this further, if you decide to pursue learning more about templates someday.

Absolutely true, but I also don’t want the language polluted with fancy tricks that just give programmers enough rope to hang themselves.

A fool can hang himself with anything. Languages should follow the principle of least surprise and shouldn’t fail miserably (coredump, exhibit undefined behavior, etc…) when used incorrectly. Making Java generics more powerful wouldn’t change any of that.

Ah, but I was doing device driver work, and SoftIce and templates didn’t get along so well…

Sorry, I don’t know anything about SoftIce, so I can’t help you there. Frankly though, that’s simply a QOI issue with respect to one vendor.

Another problem was the horrible error messages that the compiler spewed forth…

Check out STLFilt, http://www.bdsoft.com/tools/stlfilt.html. It’s free, open source, and should do exactly what you’re asking.

God bless,
-Toby Reyelts

Good article.

Glad you enjoyed it.

Nice attitude.

It’s derived from personal attacks and constant affirmation of misinformation and denial of facts.

For someone who concludes with ‘God bless’ after every post, you certainly have a remarkable lack of consideration for another person’s point of view.

I have little patience for obvious nonsense, especially when it comes from those who refuse to avail themselves of any of the relevant publicly available information. I strive to be patient for those who genuinely care.

I don’t really see the InvocationHandler code being generated in the generated Proxy0.class tho

I never said it was. I said that Proxy generates classes that directly invoke the InvocationHandler - in opposition to your statement that Proxy simply wraps dynamic dispatch to the InvocationHandler.

I got the impression that I should have no problem with what STLs are doing because Proxies are doing the same thing…and, again, my problem with STL is the copy-paste coding style not so much as a ‘code generator’ like the Proxy is

Chris, you leave me no choice. I don’t have the time to argue against templates as “copy-paste” with you anymore. You won’t read the facts on your own and you won’t listen to the facts either. I do hope this discussion eventually pushes you into learning more about them.

Did you mean remove casts?

No, I meant what I said. The compiler will generate casts in the bytecode where you have none in your source code. (As compared to C++ templates, where there are no hidden costs).

And doesn’t generics give you compile time type safety of collections.

Yes - I consider this to be the same feature as adding casts. As an aside, Java generics will let you perform unsafe assignments with warnings.

I’m a big fan of find out problems at compile time.

As am I, yet in the seven or so odd years I’ve been writing Java code, I’ve only casted a container element to the wrong type once.

Perhaps the label ‘Generics’ placed on the parameterized type functionality is stretching the term too much based on your C++ background.

Yes, perhaps Java generics should be renamed “Type Auto-casting with Bonus Covariant Return Types”. (This is also hilarious. Rather than introduce covariant return types as a first class Java feature, we’re creating a hacked implementation of it that is joined with the support for generics).

God bless,
-Toby Reyelts

[quote]Check out STLFilt, http://www.bdsoft.com/tools/stlfilt.html. It’s free, open source, and should do exactly what you’re asking.
[/quote]
THANK YOU! See, there’s another reason I should keep up with reading those C++ journals :wink:

Suppose that this was the case only to provide byte-code compatability for legacy JVMs, but in the future the byte-code spec would be modified to support the parameterized-type natively? It should meean that no casts are performed at runtime. This would be good, no?

-Chris

Suppose that this was the case only to provide byte-code compatability for legacy JVMs, but in the future the byte-code spec would be modified to support the parameterized-type natively? It should meean that no casts are performed at runtime. This would be good, no?

It would be an incremental improvement.

God bless,
-Toby Reyelts

[quote]Suppose that this was the case only to provide byte-code compatability for legacy JVMs, but in the future the byte-code spec would be modified to support the parameterized-type natively? It should meean that no casts are performed at runtime. This would be good, no?
[/quote]
This might not need the VM spec be modified.

The native JIT compiler could possibly optimize the casting verification away based on extended properties found in the class file left there by the java compiler.

I still find generics in Java, although somewhat useful, to be a rather bulky hack. I mean, it’s not a very elegant solution, adding hidden methods (not in the source code) behind your back. This is of course unavoidable when you aim to maintain backwards compatibility.

Seb

This might not need the VM spec be modified.

Yes, strictly speaking, it is possible that some improvements to Java generics could be realized without updating the VM spec. Of course, this would then rely on new unspecified conventions, for example, the use of special new JVM attributes for generics. I have a feeling that Sun felt that that would be tantamount to a spec change.

I still find generics in Java, although somewhat useful, to be a rather bulky hack.

I agree that it’s pretty much a hack, although some people may feel that it was elegant considering the particular goals (backwards compatibility, container auto-casting) the spec team had in mind.

God bless,
-Toby Reyelts