The Artima Developer Community
Sponsored Link

Weblogs Forum
The Positive Legacy of C++ and Java

210 replies on 15 pages. Most recent reply: May 8, 2009 11:50 PM by Daesung Park

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 210 replies on 15 pages [ 1 2 3 4 5 6 ... 15  | » ]
Bruce Eckel

Posts: 875
Nickname: beckel
Registered: Jun, 2003

The Positive Legacy of C++ and Java (View in Weblogs)
Posted: Mar 14, 2009 12:12 PM
Reply to this message Reply
Summary
In a recent discussion, there were assertions that C++ was a poorly-designed language. I was on the C++ Standards Committee for 8 years, and saw the decisions take place. I think it's helpful to understand the language choices for both C++ and Java in order to see the bigger perspective.
Advertisement

That said, I hardly ever use C++ anymore. When I do, it's either examining legacy code, or to write performance-critical sections, typically as small as possible to be called from other code (my preferred approach is to quickly write an app in Python, then profile it and if necessary improve performance by calling small portions of C++ using Python's ctypes library).

Because I was on the C++ Standards Committee, I saw these decisions being made. They were all extremely carefully considered, far more so than many of the decisions made in Java.

However, as people have rightly pointed out, the resulting language was complicated and painful to use and full of weird rules that I forget as soon as I'm away from it for a little while -- and I figured out those rules from first principles while I wrote books, not just by memorizing them.

To understand how the language can be both unpleasant and complicated, and well designed at the same time, you must keep in mind the primary design decision upon which everything in C++ hung: compatibility with C. Stroustrup decided -- and correctly so, it would appear -- that the way to get the masses of C programmers to move to objects was to make the move transparent: to allow them to compile their C code unchanged under C++. This was a huge constraint, and has always been C++'s greatest strength ... and its bane. It's what made C++ as successful as it was, and as complex as it is.

It also fooled the Java designers who didn't understand C++ well enough. For example, they thought operator overloading was too hard for programmers to use properly. Which is basically true in C++, because C++ has both stack allocation and heap allocation and you must overload your operators to handle all situations and not cause memory leaks. Difficult indeed. Java, however, has a single storage allocation mechanism and a garbage collector, which makes operator overloading trivial -- as was shown in C# (but had already been shown in Python, which predated Java). But for many years, the partly line from the Java team was "Operator overloading is too complicated." This and many other decisions where someone clearly didn't do their homework is why I have a reputation for disdaining many of the choices made by Gosling and the Java team.

There are plenty of other examples. Primitives "had to be included for efficiency." The right answer is to stay true to "everything is an object" and provide a trap door to do lower-level activities when efficiency was required (this would also have allowed for the hotspot technologies to transparently make things more efficient, as they eventually would have). Oh, and the fact that you can't use the floating point processor directly to calculate transcendental functions (it's done in software instead). I've written about issues like this as much as I can stand, and the answer I hear has always been some tautological reply to the effect that "this is the Java way."

When I wrote about how badly generics were designed, I got the same response, along with "we must be backwards compatible with previous (bad) decisions made in Java." Lately more and more people have gained enough experience with Generics to see that they really are very hard to use -- indeed, C++ templates are much more powerful and consistent (and much easier to use now that compiler error messages are tolerable). People have even been taking reification seriously -- something that would be helpful but won't put that much of a dent in a design that is crippled by self-imposed constraints.

The list goes on to the point where it's just tedious. Does this mean Java was a failure? Absolutely not. Java brought the mainstream of programmers into the world of garbage collection, virtual machines and a consistent error handling model (especially if you subtract checked exceptions, which is possible using techniques I show in Thinking in Java, 4e). With all its flaws, it moved us up a level, to the point where we are now ready for higher-level languages.

At one point, C++ was the leading language and people thought it would always be so. Many think the same about Java, but Java has made it even easier to replace itself, because of the JVM. It's now possible for someone to create a new language and have it run as efficiently as Java in short order; Previously, getting a correct and efficient compiler took most of the development time for a new language.

And we are seeing this happen -- both with higher-level static languages like Scala, and with dynamic languages, both new and ports, like Groovy, JRuby and Jython. This is the future, and the transition is much smoother because you can easily use these new languages in conjunction with existing Java code, and you can rewrite bottlenecks in Java if necessary.

Java itself will diminish, just as C++ did, to be used in special cases (or perhaps just to support legacy code, since it doesn't have the same connection to hardware as C++ does). But the unintentional benefit, the true accidental brilliance of Java is that it has created a very smooth path for its own replacements, even if Java itself has reached the point where it can no longer evolve. All future languages should learn from this: either create a culture where you can be refactored (as Python and Ruby have done) or allow competitive species to thrive.


Michele Costabile

Posts: 2
Nickname: cosmic
Registered: Jan, 2008

Re: The Positive Legacy of C++ and Java Posted: Mar 15, 2009 2:53 AM
Reply to this message Reply
I think that one serious burden of C++ was the lack of a standard library.
If I recall it right, Stroustroup wrote in "The Design and Evolution of C++" that he delayed a standard library in favor of multiple inheritance. I would have enjoyed it more the other way.
In 1996 I felt that C++ was as a lot more bureocracy in my code with moderate benefits, except for GUI programing, that I did not do. Things that I would have easily done in Ansi C where somewhat shorter to code but not that much easier. Later, I made a project with Borland C++ and STL and had a lot of fun.
In the meantime I already had switched to Java, because all the nightmares of a large project I worked in, that caused weeks of debugging and testing, would have just been compilation errors.
I had to swallow a virtual machine that I would not have asked for and a poor GUI tolkit, but the language was so attractive.
Today I think that JRuby is a fantastic way for a Java shop to lighten up some of the tasks with a dynamic language.

bug not

Posts: 16
Nickname: bugmenot2
Registered: May, 2005

Re: The Positive Legacy of C++ and Java Posted: Mar 15, 2009 5:16 AM
Reply to this message Reply
I wonder - what do you think about D (by digitalmars)? Is it a well-designed language? Does it have any mistakes like Java?

Casper Bang

Posts: 12
Nickname: mrmorris
Registered: Nov, 2007

Re: The Positive Legacy of C++ and Java Posted: Mar 15, 2009 7:40 AM
Reply to this message Reply
"Java brought the mainstream of programmers into the world of garbage collection, virtual machines and a consistent error handling model"

Not to mention, design by contract. Up until then, only academic languages carried that flag forward. While I salute Java for pushing these things, I'm pretty sure I won't look back and miss the constraints of it. Darwinian language evolution, survival of the fittest features will continue to prevail. It's a good thing languages are replaced, it means we learned something.

lawrence fisher

Posts: 1
Nickname: lofi
Registered: Mar, 2009

Re: The Positive Legacy of C++ and Java Posted: Mar 15, 2009 10:30 AM
Reply to this message Reply
This article is presents itself as a history of technical advances of languages but is in fact a record of the egotistical turmoil of seeing your backed technology fade from the mainstream.

As much as the studied decisions of the C++ design committee taught the world about programming languages, their true legacy is those things they taught us not to do.

Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Re: The Positive Legacy of C++ and Java Posted: Mar 15, 2009 1:17 PM
Reply to this message Reply
> <p>It also fooled the Java designers who didn't understand
> C++ well
> enough. For example, they thought operator overloading was
> too hard
> for programmers to use properly. Which is basically true
> in C++,
> because C++ has both stack allocation and heap allocation
> and you must
> overload your operators to handle all situations and not
> cause memory
> leaks. Difficult indeed. Java, however, has a single
> storage
> allocation mechanism and a garbage collector, which makes
> operator
> overloading trivial -- as was shown in C# (but had already
> been shown
> in Python, which predated Java). But for many years, the
> partly line
> from the Java team was "Operator overloading is too
> complicated." This
> and many other decisions where someone clearly didn't do
> their
> homework is why I have a reputation for disdaining many of
> the
> choices made by Gosling and the Java team.</p>
>
I'm not sure where you got the impression that the choice of leaving out operator overloading was because someone didn't do their homework. I remember asking this Gosling in one of my interviews of him why he left out operator overloading (I don't think that question and answer ended up getting published). What he basically said to me, is what I heard him say in other contexts: Gosling felt that the level of operator overloading abuse he had seen in practice in other languages (I'm not sure if this was just C++, but certainly included C++) had outweighed the benefits of it. That's all. It was a subjective design choice.

Either way it is a tradeoff. Scala allows you to define methods with operator names. This is one way Scala can help you design libraries for which the client code is clear and concise, but I've already seen places where operators were used in places I think non-operator names would have been better. I think it would be tough to allow operator overloading in a language without making it also possible for people to abuse them. And of course one person's example of operator abuse can be another person's lightbeam of code clarity.

Anyway, I think the decision on what to do about operators is a non-obvious choice in language design, and each way you can go has pluses and minuses. One thing Scala does is it really goes in the other direction of letting you use operator characters in just about any identifier. It doesn't restrict you to just methods, and it doesn't restrict you to just things like +, -, *, /, etc. It is a different attitude. One thing I remember Gosling saying is that the one use case he felt was very compelling for operator overloading was numeric analysis. i.e., number crunching apps.

> <p>There are plenty of other examples. Primitives
> "had to be included for
> efficiency." The right answer is to stay true to
> "everything is an
> object" and provide a trap door to do lower-level
> activities when
> efficiency was required (this would also have allowed for
> the hotspot
> technologies to transparently make things more efficient,
> as they
> eventually would have).
>
By trap door do you mean something at the source code level? I asked this question of Gosling also, and he said:

Bill Venners: Why are there primitive types in Java? Why wasn't everything just an object?

James Gosling: Totally an efficiency thing. There are all kinds of people who have built systems where ints and that are all objects. There are a variety of ways to do that, and all of them have some pretty serious problems. Some of them are just slow, because they allocate memory for everything. Some of them try to do objects where sometimes they are objects, sometimes they are not (which is what the standard LISP system did), and then things get really weird. It kind of works, but it's strange.

Just making it such that there are primitive and objects, and they're just different. You solve a whole lot of problems.

From: http://www.artima.com/intv/gosling313.html

This was back in 2001. I'm not sure how the state of the art at that time differs from today, but what the Scala compiler seems to show is that you can model everything as an object at the source code level and let the compiler compile to primitives where possible. This way you get to have your cake and eat it too. Having the cake is that at the source level, you have one consistent object model. But you still get the optimization benefits of primitives in the bytecodes. There's no "trap door" at the source level in Scala, and the compiler seems to do a pretty good job of figuring out when to box and when to use primitives. The one thing that shows up in Scala's object model is that you can't check "value types" (which map to Java's primitive types) for reference identity. They don't have a method for that.

> <p>When I wrote about how badly generics were designed, I
> got the same
> response, along with "we must be backwards compatible
> with previous
> (bad) decisions made in Java." Lately more and more
> people have gained
> enough experience with Generics to see that they really
> are very hard
> to use -- indeed, C++ templates are much more powerful and
> consistent
> (and much easier to use now that compiler error messages
> are
> tolerable). People have even been taking reification
> seriously --
> something that would be helpful but won't put that much of
> a dent in a
> design that is crippled by self-imposed constraints.</p>
>
My understanding of the decision to go with erasure had to do with Sun had just shipped a new collections library, and they didn't want to ship another one. I think they felt it would be too disruptive for users. But it wasn't just collections that would have needed duplicating. Every library would need to be replicated to be generified, and by that time Java had a lot of libraries. Servlets for example. You'd need a new one of those to generify it. And so on and on.

The downside of erasure is that there's now two different notions of the type system you have to keep in your head, the compile-time one and the run-time one. And that adds complexity. One upside of erasure is that reification would have driven the creation of another version of every Java library designed at that time, which would have added a different kind of complexity. Another upside of erasure I had heard expressed once is that it may leave room for more type system innovation in languages that run on the JVM. I actually heard this as a complaint about the CLR having reified types, in that they kind of constrained languages to just those types.

So again, here's a tradeoff. I would still rather have reified types, but given the situation, I'm not convinced it was a bad decision to go with erasure on the JVM. If they had gone with reification, we'd have a Java API filled with generic and non-generic versions of most things. Yes, because of erasure you have to keep two different models in your head, but I'm able to handle it. Most of the time I don't use reflection, so usually I just have to keep the compile-time model in my head. And once again, Scala showed me that there are ways to get at the erased type information when you need it. It is possible. In ScalaTest, for example, you check that a bit of code throws an expected exception like this:


intercept[StringIndexOutOfBoundsException] {
"hi".charAt(-1)
}


Here, intercept is a method call that will ensure the bit of code throws a StringIndexOutOfBoundsException. But if you think about it, how could this work because the exception type is specified as a type parameter, which is erased on the JVM. Well Scala provides a way for me to find out at runtime what that type parameter was in the source code, which is basically and end-run around erasure.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: The Positive Legacy of C++ and Java Posted: Mar 15, 2009 5:48 PM
Reply to this message Reply
I've read a lot of articles about the relative merits of different languages and the 'big idea' with Java seems to be missed by so many authors. Where Java succeeded that so many fail to acknowledge is in the area of team development. It's a language that says you should have the power of a given feature but only if that feature doesn't create problems for other people trying to read and maintain your code. Note at this point that I believe that it has had some significant failures in this regard.

Most languages either tout ease or power. C++ was about power. Want to flex your nerd muscles. C++ is your language. VB was about ease. If you just need to get something up and running in short order, VB's your language.

Java doesn't address either of these well. And I think this is where a lot of people get stuck trying to understand its success. It's not exteremely powerful and it's not extremely easy. Kind of mediocre, one might think. But when you throw a large team into the mix, Java starts to make sense. For example, I've never heard of Bruce's alleged reason for the lack of operator overloading before. I've always heard that it's because it's too easy miss that an operator is overloaded. That is, you are looking at the code and thinking that '+' does the obvious but it does something else that you didn't consider. Personally I am on the fence about operator overloading but I haven't missed it much in Java.

When I read a lot of these kinds of discussions about Java, it seems to me that the author is only thinking about how the language affects the lone developer working in isolation. And a lot of languages seem to be focused on that. They don't consider how the features in the language will affect team development. Java is a language where the designers have considered that. I can look at any Java code snippet and have a very good understanding of what it does, that is, I know exactly what I need to find out to understand it perfectly. I personally might want to change the semantics of a call here and change the meaning of a operator there but I don't want anyone else doing that on my code base.

Having said that, Java ad the Java community has made some big errors in this department. Reflection greatly reduces the transparency of code and byte modifying tools are likewise obfuscating. The combination of these two tools are the foundation of pretty much all of the popular Java frameworks that Java developers are expected to use. Generics and other 1.5 features greatly increased the complexity of the language. This makes it harder for developers to communicate through code.

But the legacy of Java is really that it addresses the problems of groups of programmers and not just the problems of the individual programmer.

robert young

Posts: 361
Nickname: funbunny
Registered: Sep, 2003

Re: The Positive Legacy of C++ and Java Posted: Mar 15, 2009 7:31 PM
Reply to this message Reply
> But the legacy of Java is really that it addresses the
> problems of groups of programmers and not just the
> problems of the individual programmer.

It's always looked much simpler to me. Java was created, from Oak of settop box fame, to run applets. That wasn't working out so well.

Were it not for the Servlet, from which sprang tomcat, jasper, and thence WebSphere, Weblogic, et al we would not be talking about java. The java web server did improve upon Apache/CGI enough to matter. It doesn't improve upon C(++) enough to matter in that arena; I would argue that as a portable assembler/systems programming language it matters not at all.

Most java programmers, few will 'fess up, are [FOLM] Framework programmers acreting ever more code into a giant hairball. Which is why some view java as COBOL with pixels.

Fred Garvin

Posts: 52
Nickname: fredgarvin
Registered: Jan, 2008

Re: The Positive Legacy of C++ and Java Posted: Mar 15, 2009 8:56 PM
Reply to this message Reply
Let's not kid ourselves. The 'big picture' with Java is, without a doubt, platform independence via the virtual machine. Don't get me wrong, Java is a pretty good language, but it wouldn't have made a dent without the VM.

The innovation springing from Java, past and present, can all pretty much be attributed to the platform, not the language per se. Java's success on the server, like the client, was at first marketing hype, Java was the steaming cup in the browser... neato. What really gave it traction, however, was platform independence. And what made it stick was Hotspot, which, aside from the VM itself, is probably the most innovative Java technology ever.

Today we see loads of interesting technology in the Java space. But it's not coming in the form of new language features. Instead a significant part of it is coming in the form of new language*s*; languages that could not exist without the VM. We have Scala, Groovy, Jython, JRuby, and many others. I'll go out on a limb and say one of these, probably one we don't know about yet, will someday unite what has become a fragmented Java community. I'll hope for it anyway... who am I kidding...

Achilleas Margaritis

Posts: 674
Nickname: achilleas
Registered: Feb, 2005

Re: The Positive Legacy of C++ and Java Posted: Mar 16, 2009 5:05 AM
Reply to this message Reply
> and well designed at the same time, you must keep in mind
> the primary
> design decision upon which everything in C++ hung:
> compatibility with
> C.

I don't think that C++ is badly designed because of compatibility with C. ADA is compatible with C, but it is a very good language, with strong engineering leading its design.

What is wrong with C++ is source code level compatibility with C. In order to be able to include C headers, C++ maintained the preprocessor system of C. That led to a strange non-context free grammar, which led to a very strange syntax which had to stay compatible with C.

I don't see why we don't have a language that:

1) has the run-time system of C, i.e. no virtual machine.
2) has optional garbage collection.
3) has the template system of C++ which makes the run-time efficient (or better yet, a compile-time language subset).
4) is orthogonal to allocation strategies, i.e. the type of access (by reference/by value) is not hardcoded into the type of the variable.
5) has an orthogonal type system, where there are no 'primitive' types, and everything is a class.

Jess Holle

Posts: 20
Nickname: jessh
Registered: Jan, 2009

Re: The Positive Legacy of C++ and Java Posted: Mar 16, 2009 5:09 AM
Reply to this message Reply
Operator overloading has other issues beyond those specific to C++ (multiple allocation models and lack of GC).

If you have a large undisciplined team, then code quickly becomes unfathomable as developers add various operator overloads classes to save keystrokes -- with little thought to clarity.

Seeing "d = ( a + b ) / c;" could mean an arbitrarily complex and deep code path in any language with operator overloading. In Java you know "there's nothing funny going on on this line", just normal arithmetic.

Sure, if you note that a, b, c, and d are not primitives, then you know there must be something special going on here. There's still the issue that operators are essentially encouraging and rewarding developers to give their methods single character names. That's great for cases where the method really is a mathematical addition or multiplication, but even then it gets messy -- for instance, vectors have dot and cross products, not just one multiplication operation.

Operator overloading is one of those features that's great if you're on a one man project where you can make all these decisions wisely for yourself as the maintainer/reader -- and a horror for a large team.

Michele Simionato

Posts: 222
Nickname: micheles
Registered: Jun, 2008

Re: The Positive Legacy of C++ and Java Posted: Mar 16, 2009 5:17 AM
Reply to this message Reply
> Operator overloading is one of those features that's great
> if you're on a one man project where you can make all
> these decisions wisely for yourself as the
> maintainer/reader -- and a horror for a large team.

I think this is excessive worrying. Python has operator
overloading and I have never heard of a single horror story
about it.

Achilleas Margaritis

Posts: 674
Nickname: achilleas
Registered: Feb, 2005

Re: The Positive Legacy of C++ and Java Posted: Mar 16, 2009 5:40 AM
Reply to this message Reply
I'd also like to note that multiple allocation models and lack of GC are not issues that have to do with operator overloading.

Operator overloading is just syntax sugar. Instead of saying


multiply(a, b)


the programmer is allowed to say:


a * b


Which is more readable. Memory allocation has nothing to do with operator overloading.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: The Positive Legacy of C++ and Java Posted: Mar 16, 2009 6:28 AM
Reply to this message Reply
> Let's not kid ourselves. The 'big picture' with Java is,
> without a doubt, platform independence via the virtual
> machine. Don't get me wrong, Java is a pretty good
> language, but it wouldn't have made a dent without the VM.

I'll go out on a limb and say that most Java shops are enterprise IT. A lot of these shops couldn't care less about platform independence. Some do but it's not that big of a deal for most.

What has made Java a good fit for these shops is that it is easy to follow Java code. Yeah, you can write unmaintainable code in any language but you have to work at it in Java. It doesn't provide a lot of the features that are so easy to abuse in other languages.

From an individual's perspective, this is terrible. If I don't want to use a feature I won't use it. Who is Sun to tell me what I should do and shouldn't do? But when you take a group of developers who have different ideas about what a good approach is, the game changes. Having a limited number of ways to do things starts making sense.

This isn't just my theory. Go on Sun's Java Forums and look at how people are advised not to use esoteric language features or tricky approaches just to save time or effort. Clarity is generally considered to be the most important aspect of Java code. The time it takes to add new features to Java is centered around whether the feature adds something significant to the language that can't easily be done in other ways.

Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Re: The Positive Legacy of C++ and Java Posted: Mar 16, 2009 9:45 AM
Reply to this message Reply
> I'll go out on a limb and say that most Java shops are
> enterprise IT. A lot of these shops couldn't care less
> about platform independence. Some do but it's not that
> big of a deal for most.
>
> What has made Java a good fit for these shops is that it
> is easy to follow Java code. Yeah, you can write
> unmaintainable code in any language but you have to work
> at it in Java. It doesn't provide a lot of the features
> that are so easy to abuse in other languages.
>
> From an individual's perspective, this is terrible. If I
> don't want to use a feature I won't use it. Who is Sun to
> tell me what I should do and shouldn't do? But when you
> take a group of developers who have different ideas about
> what a good approach is, the game changes. Having a
> limited number of ways to do things starts making sense.
>
I think Java code can be easy to follow in the sense of all the details of how the code works, while at the same time harder to follow in the sense of what the programmers higher level intent was for that code. This may be the right tradeoff for enterprises, but I see it as a tradeoff. Because Java's syntax is more rigid, when you look at Java code you can figure out what's a method call and what's a field access, etc. But you also get a lot of boilerplate and verbosity that can hide the intent of the programmer.

One of the things I've noticed about Scala is that it can go in the other direction. The syntax is very flexible such that you can get rid of boilerplate and verbosity. When you design a library in Scala, you can simmer the client code down to just the most intent-revealing miminum. I think that helps readability in the sense of figuring out the programmer's intent. But it hurts readability in the sense of figuring out how the code is actually working. There are ways to figure out how things are working, of course, but it isn't as obvious up front as in Java code.

I suspect the readability of Java's rigid syntax was indeed part of its success, but the verbosity that goes along with that syntax predictability is now one of the main complaints people have about it compared to other languages.

Flat View: This topic has 210 replies on 15 pages [ 1  2  3  4  5  6 | » ]
Topic: Should I use a netbook as my main development platform? Previous Topic   Next Topic Topic: Social Newsfeeds: The Next Big Thing

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use