Anders Hejlsberg, the lead C# architect, talks with Bruce Eckel and Bill Venners about C# and Java generics, C++ templates, contraints, and the weak-strong typing dial.
Generics in C#, Java, and C++, Part 7
About The Author
Eugenia Loli
Ex-programmer, ex-editor in chief at OSNews.com, now a visual artist/filmmaker.
Follow me on Twitter @EugeniaLoli
88 Comments
That might work for some local variables, but for most variables this is impossible since there can be cases where it is impossible to know at compile time wether reference semantics will be used on a member or not.
For example if you define an Integer[] and then pass it to some opaque methods there is no way the compiler can know wether one of these methods takes a reference of one of the Integers in the array. So to be on the safe side the compiler has to represent the Integer[] as an array of references even though it would be an order of magnitude more efficient to represent it as an int[]
And even if it were possible to optimize this transparently, this will probably not make it into java before 2035, so it is irrelevant to the java vs. C# discussion.
And besides value semantics are much more natural for numbers than reference semantics anyway.
Good, then what I’ve been saying for years is not just wild speculation on my part and in fact, that the compiler could figure out if a type can be placed on the stack.
Unfortunatly it would require a few things that make it a PITA for Java.
1. you would have to add new instructions to put values on the stack.
2. you would have to modify the VM to put classes on the stack.
3. it would only be valid in a very limited number of cases, like final or static function calls. When dealing with a polymorphic function dispatch it would destroy the optimization.
4. Java people move slow. While not really a technical issue, tuttle is right in that Java is not the quickest moving language out there. It would be nice if there was a more ‘tracked’ java developement community, more like linux where there was a beta version of Java for those of us that want it. Like right now, there is a version of 1.5, but the general development community cannot download it.
5. Like tuttle said, this optimization does not apply to arrays, which means that java has, and will continue to have problems in the area of numeric processing. I would say that with out value types, it will be very hard to achieve similar performance in Java for data processing. Value types allow you to optimize your data accesses since the data is already laid out correctly in memory (in a linear fashion instead of haphazardly all over the place). Java currently has no interface for the programmer to enforce memory constraints (with respect to positon in RAM). This is a major drawback of Java.
The more I look at C# the more I realize that it probably will be the future language of choice for most Windows development. Being hosted in the .NET enviroment will only speed its transition. Java has a drawback that you must painstakingly wrap all you C/C++/whatever code in order to interface with it. The .NET enviroment gets rid of that restriction. I think that the MONO guys see that possibility, but don’t have the resources to make that idea a reality like MS does.
On the Microsoft product, they can push anything they want, so you could be writing C on year and C# the next and some other new fangled language three years from now. I like the way that Linux handles the problem by being a platform, it leaves you with choices, you can use C, C++, Python, Perl, the shell, C#, ML, Fortran, Scheme, Java, etc. You don’t have to worry about any vendor phasing something out of their product line. Probably the best value on Linux is to learn the C programming language because the majority of the ‘systems’ are implemented in C, and the platform is open, so you can work with the code to develop software that needs new hardware mechanisms (another market). These types of uses of generic programming give it the opportunity to be used to implement systems rather than solutions. I don’t like how C# has to be an only way, where as in C the programs will utilize a variety of languages and the application will be modular so that someone maintaining it can implement the front end for some other toolkit and not be dependent upon one library. I see C# being very product oriented and not scientific and I’d rather have a choice, so the open platform makes all of the difference. it would be great if the vendors built libraries that target a platform rather than a product line.
A few years ago MS was pushing VB, and VB was the ultimate language. Now you probably won’t even be able to run traditional VB on MS’s next product (Longhorn). There are many people out there who want to use traditional VB though, but MS has to force them not to, because they want to sell new tools. Now they are talking about how C# generics are better than any other, yet C# generics have hardly made it into .Net. How long have they been there, a month or two? Somehow I don’t think that MS provides the whole story, but they are out to sell tools to programmers at high prices.
>1. you would have to add new instructions to put values on
> the stack.
> 2. you would have to modify the VM to put classes on the
> stack.
The point is, that value types will not be added to
Java, as it would unnecessarily complicate the language.
This would go against one of the basic ideas of Java, ie.
being a *simple* language. Introducing value types would,
in my opinion, be a step backwards for Java, as it would
put some minor performance improvements over the ease
of use (as soon as you have value types (that are more
complex than an int or some other primitive), you
have to distinct between them and reference types,
which have different semantics). The performance gain
would actually be not as big as people might suspect,
as the development of more sophisticated GCs continues
(the performance object allocation of current generational GC is actually close to the performance of stack allocation);
> 4. Java people move slow. While not really a technical
> issue, tuttle is right in that Java is not the quickest
> moving language out there.
Funny… I just talked to a C++ guy, that complained
about Java changing to fast for his taste…
For some reason, people have been complaining about
Java changing too slowly, but frankly, I don’t get it;
I really prefer to get to know a language and to get
experience with it, to constantly learning new language
constructs just to stay abreast of the development.
Using any .Net high level languages, I am forced to build applications the way the vendor dictates they should be built. I am forced to use the vendors library as the way to have an integrated solution with the rest of the vendors product line. I am constantly told every four months about a new feature and how it is better than anything else in the world. If that vendor wants to change everything in four years, than I am forced to follow. I have no control over the factors of production. Why would I want to be a victom? I’d rather use a platform that allows the users to lead the development of new libraries and hardware because they have constructed general software systems that require new hardware mechanisms provided by large vendors, and on the specialized end the customer demand is being met by small and medium sized software business. If there is any progress for the developer, it is the language that gives him the most control over the direction of software development. The product lines Java and .Net/Mono are not good choices.
> Introducing value types would, in my opinion, be a step
> backwards for Java, as it would put some minor performance
> improvements over the ease of use
>
So a factor of 4 or more is a minor performance improvement for you?
Allocating and deallocating on the heap will never be even remotely as fast as just pushing something on the stack. And a million tiny objects spread all over the heap will never be as fast as a nice linear chunk of memory.
If you do not do numerical computing or graphics you will never notice this, but if you do java is unusable.
If you do not do numerical computing or graphics you will never notice this, but if you do java is unusable.
I wouldn’t call it unusable, but it’s a definiate drawback.
But you’re right, for numerics and graphics java is not the language of choice. But it was never designed to be the swiss army knife of languages, and I think that anyone saying that it should be is silly. You can get acceptable performance out of java for simple graphics and if you want high performance then you should use a language that can be highly optimized.
From the article,
“Let’s start with versioning, because the issues are pretty easy to see there. Let’s say I create a methodfoo that declares it throws exceptions A, B, and C. In version two of foo, I want to add a bunch of features, and now foomight throw exception D. It is a breaking change for me to add D to the throws clause of that method, because existing caller of that method will almost certainly not handle that exception.”
This is why Java has the java.lang.RuntimeException class. This exception, and any exception derived from it, is not checked (i.e. does not require explicit declaration or handling).
Well, there’s no doubt that c# and .NET in general are the future of windows programming. Nobody is going to miss win32api or MFC. MS has made some not to subtle suggestions to even VB.NET and VB programmers that it’s wise to learn c#, even though you know MS will probably support some VB variant until the sun explodes.
Regarding Mono, it’s too soon to see what kind of impact its going to have even though I suspect it’ll be substantial. Eugenia had it right on when she wished to see c#/Mono to be a primary means of programming Gnome in the future. In fact, I’ll go so far that it might be the only thing that saves Gnome from the superior technology of KDE. In most regards, Bonobo is a failure compared to KDE’s component technology. Once Mono gets over that 1.0 hump, key Gnome developers embrace it(I’ve seen blogs of key gnome people saying they like it), people get over their fear of “Microsoft made”, and the gtk# bindings are there completely, I think you’ll see mono taking off. There are just too many advantages of c#/mono over the way things are currently done for Gnome. Primarly straight c(ugh), or scripting languages like Perl or Python. Actually, there is a c compiler for IL(dotgnu) and I hear that Perl and Python are targetting IL too. Once you get the toolkit bindings done for one .NET language(as long the bindings are CLS compliant), then the bindings are automagically done for all other mono/.NET languages. This is a huge boost for say Gnome because Gnome has always had a problem with each bindings implementation being not complete or buggy or a revision back. KDE doesn’t have this problem as much since your using c++ and with the new kdevelop, it’s almost VC like in doing applications, but a whole lot better with a better toolkit.
Hopefully, Novell will pump a lot of resources into its subsidiary Ximiain.
The Linux platform will always give you a choice of what to use. Traditional gnome is unaffected by Mono. If Mono wants to PInvoke the Gnome functions than it is free to create it’s C# wrappers, but that doesn’t have any bearing on Gnome programmers who will continue to use Gnome and C, if they choose to. The application should separate the front end from the engine, and you should be able to use any GUI library be it QT, Gnome, Mono, wxWindows, Gtkmm, etc.
For example if you define an Integer[] and then pass it to some opaque methods there is no way the compiler can know wether one of these methods takes a reference of one of the Integers in the array.
—
You’d be surprise how often this works. If you’ve got a good global optimizer, the only code for which the compiler will have to be conservative in its analysis is for code that is dynamically loaded at runtime. Unless you are regularly in the habit of giving references to large arrays to plug-ins (which isn’t a great idea from an encapsulation standpoint) it shouldn’t be a problem in practice.
So to be on the safe side the compiler has to represent the Integer[] as an array of references even though it would be an order of magnitude more efficient to represent it as an int[]
—
A better way to handle arrays is via proper (read: not like Java 1.5) generics. Dylan has a cool thing called limited arrays, which are a lot like C++ templated vectors. The only code change you have to make is instead of creating a regular array, you create a limited array. This keeps storage allocation orthogonal to the type system. Thus, you can put any type of object (in theory — limited types are an unfortunately under-explored part of Dylan) in a limited array, not just special “value types.”
And besides value semantics are much more natural for numbers than reference semantics anyway.
—
As I said, value semantics are valuable from a design standpoint. In Dylan you can declare a type to be a value type because it should logically have value semantics. However, that is a design decision, not an optimization one. What I hate about C# and Java’s handling of value types is that they’re really hackish. C# shackles the concept of value types to storage allocation, when the two concepts are orthogonal. Java just says that there are a few God-given value types built into the language, and everything else shalt be a reference type. Even C++ handles is more logical and orthogonal in this regard, which is a rare thing indeed!
You tend to troll quite a lot on these boards, but I’ll bite on the last comment you made.
Nobody ever said that your not going to be able program in *pick your favorite language* using *pick your favorite toolkit* in Gnome or whatever. What you have is the ease of development on a particular platform and could the ease of development generally be any better. Let’s compare KDE and Gnome. In KDE, you’ve got bindings for some languages but the vast majority of app work is done in c++. C++ allows a much higher abstraction in its app framework/sdk. The Gnome developers have said for a while now that using c/gtk+/gnome for regular app development in Gnome isn’t very wise, but most of it is done in c anyway. The answer probably lies in the fact that most Gnome people are not going to want to use something like Python or Perl. I have nothing against these languages per se, but they have their warts(including, but not limited to bindings issues). The great thing about mono is that you can bring in a much larger audience to what would be a limited number of decent programmers on Gnome coupled with the fact that the ease of development on Gnome is far behind that on KDE and that c# is objectively a decent language when compared to many other offerings. Just look at the new Kdevelop for something that is arguably as good as VS. IDE’s is something that MS does know how to do good. Gnome is still stuck in some waste-land of Anjuta being forked over and over while basically having no real active development. Anjuta or anything other fork is probably a couple years away from being a modern, first-class IDE. Once Monodevelop is ported to gtk+(and it’s moving fast), you’ll have a decent IDE with a first-class language to use with it, along with easy pluggability for other language.
The funny thing is that I’m primarly a KDE 3.2 user for various reasons, but find c++ to still be cludgy even though KDE does have a decent framework and I’m not a big fan of the QT license. I want Gnome to compete, but I just don’t see Gnome competing against KDE offerings in the near future, until they come up with something new.
You tend to troll quite a lot on these boards, but I’ll bite on the last comment you made.
Nobody ever said that your not going to be able program in *pick your favorite language* using *pick your favorite toolkit* in Gnome or whatever. What you have is the ease of development on a particular platform and could the ease of development generally be any better. Let’s compare KDE and Gnome. In KDE, you’ve got bindings for some languages but the vast majority of app work is done in c++. C++ allows a much higher abstraction in its app framework/sdk. The Gnome developers have said for a while now that using c/gtk+/gnome for regular app development in Gnome isn’t very wise, but most of it is done in c anyway. The answer probably lies in the fact that most Gnome people are not going to want to use something like Python or Perl. I have nothing against these languages per se, but they have their warts(including, but not limited to bindings issues). The great thing about mono is that you can bring in a much larger audience to what would be a limited number of decent programmers on Gnome coupled with the fact that the ease of development on Gnome is far behind that on KDE and that c# is objectively a decent language when compared to many other offerings. Just look at the new Kdevelop for something that is arguably as good as VS. IDE’s is something that MS does know how to do good. Gnome is still stuck in some waste-land of Anjuta being forked over and over while basically having no real active development. Anjuta or anything other fork is probably a couple years away from being a modern, first-class IDE. Once Monodevelop is ported to gtk+(and it’s moving fast), you’ll have a decent IDE with a first-class language to use with it, along with easy pluggability for other language.
The funny thing is that I’m primarly a KDE 3.2 user for various reasons, but find c++ to still be cludgy even though KDE does have a decent framework and I’m not a big fan of the QT license. I want Gnome to compete, but I just don’t see Gnome competing against KDE offerings in the near future, until they come up with something new.
Sir, you are a troll. I understand your zealotry for mono, but it’s future is dicey. gtk+ is alive and kicking, and it will take more than PR, Hype and marketing for mono to displace it.
C# might be a great language, and .NET a “flawless” platform, but the fact remains that developers, like myself, don’t want to be tied to a manner of thinking, a particular vendor or worst of all Microsoft.
As for your trolling on Anjuta, all I have to say is good work. And could you please site where the gnome developers said developing apps in c/gtk+/gnome is a foolish idea?
I normally ignore your type, but I’ll bite on the last comment you made.
Hjelsberg is brilliant. Seriously. I was skeptical about C# but, after using it for the past year, I can honestly say that it (and Java) are going to bury C/C++ as the predominant languages within the next 7 to 10 years.
A few years ago MS was pushing VB, and VB was the ultimate language.
Oh, come off it. MS never said that VB was the ultimate language. Everybody who coded (and codes) in VB knew/knows its limitations and strengths. I’ve never heard it suggested by MS that VB was anything more than a RAD dev tool.
C# might be a great language, and .NET a “flawless” platform, but the fact remains that developers, like myself, don’t want to be tied to a manner of thinking, a particular vendor or worst of all Microsoft.
Mono isn’t tied to Microsoft. The C# compiler is freely available.
I don’t need Anjuta to write a program. I don’t care for monolithic tools like VS.Net. I use emacs and it works well. I like C, and Gtk+ is a good Widget Toolkit for developing GUI’s on Linux. I’ve never heard any gtk+ programmer complain, btw there is a new book comming out on Gtk+ 2.0.
I like Standard C++ because the language provides mechanisms for multi-paradigm programming. There are Standard C++ bindings for Gtk+, so that makes things easier. The Boost library and libsigc++ are also useful.
I don’t mind QT being around, as well as wxWindows or Mono. People can choose to use them, that’s great, the more the better. The only thing that I will avoid is being locked in, because lock in doesn’t help me very much.
Sir, you are a troll. I understand your zealotry for mono, but it’s future is dicey. gtk+ is alive and kicking, and it will take more than PR, Hype and marketing for mono to displace it.
Wow, put down the crackpipe. I guess your totally unaware that the most mature toolkit for mono is gtk# and most mono developers use that to do gui work, but never put it past someone to talk out their ass when they’re completely clueless about a subject.
Oh, and as someone else pointed out, mono has nothing to do with MS. Ximian too the ecma specs and went from there.
Java and C# are not the most well-designed and orthogonal languages out there. I think we can safely agree on that. My personal favorite is a FP language called clean. But unfortunately I often have to work with those two languages.
The C# value types might not be as good as those in other languages, but at least they give me and other class library designers the option to write high performance numerically oriented code in a managed language, so from a pragmatic point of view C# wins. Something like managed DirectX 9 would not be possible in java.
I think long-term it is much more important that the .NET vm has better support for value types and is more language agnostic, so if a very nice .NET language comes along I can immediately use it with the whole .NET library.
I don’t need Anjuta to write a program. I don’t care for monolithic tools like VS.Net. I use emacs and it works well. I like C, and Gtk+ is a good Widget Toolkit for developing GUI’s on Linux. I’ve never heard any gtk+ programmer complain, btw there is a new book comming out on Gtk+ 2.0.
Nobody ever said you need anjuta to write a program, and obviously you’re free to use Emacs if you wish. Personally, I despise it. Its like some IDE that is stuck in the 70’s. I’ll stick with vim if need be. But the fact of the matter is that many smart developers want a decent IDE. How many java developers are going back to Emacs after trying Eclipse or Intellij…not many I bet. You’re not elite if you use emacs or vim. Some people just want to move into the 21st century with their development tools.
Regarding gtk+, it’s a very good toolkit for c and gtkmm is very nice for c++. Mono is wrapping up gtk+ with gtk#, and it’s decent. I think it still has some warts on it regarding a lot of the c’isms that creep into bindings to other languages from c, but it works and development continues at a brisk pace.
A good Makefile will ease working with multiple files from the shell. All I want from the IDE is for it to format the code so that the spacing is nice. Beyond that I will invoke from the shell, other tools for documentation and debugging.
I’m more interested in learning about my open source system and C# does nothing for me in that regard, only C is useful for this type of work. I don’t want to use Linux like some proprietary OS. I want to use the strengths of Linux. I have to get into the source code and learn how to implement systems. I don’t really care about any GUI libraries, but I’ve looked at Gtk+ and it is more than capable of doing the job…but I have to be able to generalize, and not blindly follow a product line.
Didn’t you guys read the ZDNet article.
Microsoft has decided that OO is DEAD.
Microsoft just KILLED Com and DCom, but to try a stab at Java, they also declared OO and Java DEAD.
So, I wonder, if you guys might want to reconsider Java, as Microsoft has just decided that you need to learn something else. Or, if you don’t agree with Bill you could drop Microsoft an email Now, and tell them your sick and tired of being jerked around. Or you could just act like sheep.
That’s the problem with Microsoft, it needs to kill it’s own tech, and BURN THRU your Time and Cash, so that it can servive.
Uhh…how about being a little more specific. What article? What’s the URL? Where has Microsoft declared OO dead (and I assume you mean by extension, C#)?
C++ doesn’t have enough checking done at compile time, so it has issues with slower development. I’m assuming it also completely lacks reflection functionality?
C++ templates are a pure compile time facility, as was noted before. But the way in which templates in C++ are instantiated makes it possible that not every constraint the template type argument must satisfy is checked up-front on the first usage of the template. You can however archive this type of checking if you please.
As for the reflection, there is some kind of run time type identification. It is in a rudimentary form, but it has some useful applications. There are some proposals to add a more sophisticated reflection mechanism to C++.
The benefits of C# generics are huge. Since C# shares the code for all non value-type instantiations of your template, you will have a much smaller working set and a much higher chance that the working set fits into the cache. So I expect that C# generic classes will be much faster than C++ generics.
Almost the same type of sharing of code is possible with C++ too, because you can share one template instantiation for every pointer type.
For in-depth programming language talks,
read the blog lambda.weblogs.com
( Maybe you finded that article there, Eugenia ? )
C++ is really poised to become an obsolete language. Most of the features that where added to the clean and simple C language seems now oddly designed when comparing them to Java and C#. The additions of generics, operator overloadings, anonymous functions and other gadgets to these languages are making C++ simply useless.
C++ had an historical interest as the lead language of the early ’90 objet-oriented gui-based software. Now, it’s legacy.
( Let me apologize for my pooooor Englosh… )
In your dreams. C++ stands stronger than ever. Comments like yours are usually written by people who gave up learning it and are now afraid that C++ might come back and take their now-favorite language, be it java, c# or whatever, away. Wise up, Java has its place, it´s not going away, and thats good. But C++ is still, and i predict it will continue to be, the #1 language for serious applications.
agreed – in fact, the respected Univeristy of Bristol, UK, don’t teach C++ as its considered such a cludge. (iirc).
I think C# is better than C++ for a lot of modern applications, but just as people have been using C for ages for scientific work on the basis that it has to be faster, I think C++ could find itself taking over that niche now.
With garbage collection, sensible error handling, strongly typed generics, a decent class library and a sophisticated built-in event delegation system that negates the need for expensive libraries or Qt moc style hacks (not that I don’t like Qt mind) C# is a pretty cool language. The only caveat is that for heavy mathematical work the IL may slow things down. That’s by no means certain though, Java can do some impressive work in tight mathematical code (in fact I think I saw a benchmarking article on this site where it beat G++ generated code).
I would nearly go as far to say that C# is better than Java. I’ve worked with Java, and it seems that lately people have focused on making the architecture pretty at the expense of the programmer – look at all those ActionListener classes for Swing, or the current Java/JSP/Struts/EL/TagLib system needed to write webpages!
The only problem is it’s from Microsoft and there is therefore a risk that non-MS non-Windows implementations could be blocked using patents or what have you. Which is a pity, as I would love to use it.
C++’s is nowhere near dead.
It’s maybe a cludge of a language, but it’s extremely powerful (and dangerous). A majority of apps will soon be written in managed languages like C# or Java but high-performance software will continue to be written in C++ for at least 10 more years, IMHO.
C is powerful because it maps very closely to the hardware. C++ has many variants, and the Standard C++ usage was too closed so it never gained popularity. Java and C# are completely different, they are tied to product lines and designed to support those product lines, their actual core language definition are similar to C++, and over time they become more and more similar to C++, maybe in the future they will be C++ too.
You are quite right saying that I have abandoned learning C++. Many years ago, I have programmed in C++, but, since, I have seen the Light of Knowledge :
C is superior to C++
When a script language doesn’t fit, when you need to write a fast and lightweight embedded software, you choose C.
For any user-friendly big app, the lack of garbage collector makes C++ absolutely awful. Ten years ago, people admitted to do memory allocation themselves. Now, it’s somewhat humiliating to waste time doing that.
C# and Java have many flaws ( I am so convinced of that that I am currently designing a new programming language ) but the range of the apps that fits for C++ is shrinking comparing with :
– Java & C# ( for Windows Apps right now )
– Script languages ( Python, Perl, Ruby, PHP, …, eventually completed with C libs ) that werent widespread in the C++ glorious days.
– Plain C for lightweight embedded. C will survive to C++.
Howdy
@ the_language_zealots
Each language is great for different uses, their is no one single ultimate language out their!
As for the article i`m now more interested in looking a little deeper into C#/Mono, the criticism about optimisation of the Java generics worries me a little too (it was one feature i`m really looking forward to) but hopefully this will be improved in future versions or maybe even if or when Java is released open source.
Well i can always dream :0)
You can use a garbage collector with C++, this has absolutely nothing to do with the language.
C maps the hardware very well, but ‘STANDARD C++’ has a powerful light weight standard library that is very strong and effective. The major problem with C++ is that it took many directions and after it was ‘STANDARDIZED’ they did not make it open and accessible. In addition Standard C++ is not tied to a product line. Anyway you can accomplish basically anything in C, but Standard C++ is better for most system implementation because facilities to deal with multi-paradigms are build into the language, unlike in C.
language out their = language out there.
There are things that you have to watch out for such as a proliferation of classes as well as God classes. Those problems are heuristics and most OOP programmers try to use OOP to solve every problem. Unfortunately OOP is not useful for every problem and it can cause ugly code as a result. Standard C++ supports multi-paradigms, but it’s too expensive to learn, so C# and Java is cheaper and it’s the language of the masses, especially since they are tied to product lines. Most of what you read about C# and Java will definately be hype.
… I’m sorry for having lighted some prog. language flames.
I initially only wanted to talk of Lambda Weblogs but I added some silly unrelated remarks. Let me aplologize.
… About Java generics, the problems resides within the Virtual Machine design. Making a language hardware dependant has always been a serious flaw and Java is actually virtual-hardware dependant. Maybe Java should be more formally splitted between the Language and the VM.
Java was a way for Sun to market a product line ontop of a monopolies operating system. There was no way to compete using Microsoft API’s because Microsoft controlled everything and blocked competition, so Java could not depend upon software, they did what they had to do. Now Microsoft copied Sun because Java was too successful, so as a monopoly does, it takes over the market by consuming it.
“With garbage collection, sensible error handling, strongly typed generics, a decent class library and a sophisticated built-in event delegation system that negates the need for expensive libraries or Qt moc style hacks (not that I don’t like Qt mind) C# is a pretty cool language.”
Garbage collection is possible with C++ (as has been pointed out already) and ist no language feature. Exceptions are available in C++, as is parametric polymorphism. The delegate/event system in .NET is certainly *not* sophisticated and you can get much more powerful signal/slot libraries in C++ either with libsigc++ or with Boost.Signals (booth are open source).
Somebody forgot just how cross-platform C/C++ are…the rest follow suit to some degree or another but java is the best in cross-platform support. However for higher-end apps…they suck. A better language than C/C++ could definetely be created but until then, they have their place.
C++, like C, is here to stay. Some applications require direct memory management.
When I mentioned expensive libraries, I meant in terms of performance, not price. I know about Boost and libsigc and have seen the former, and it’s a nice way of dealing with events in C++. However it’s not built in. Likewise while C++ has exceptions, they can be ANYTHING! You can throw numbers (errno?), strings, hand-rolled ultra-cool exception classes – it’s a bit of a nightmare. This is what I was referring to by sensible error handling.
The thing is that while it is possible to do those things you mentioned in C++, all these features are a core, natural part of the C# language (not a library of any sort) and are easier to use, and in some cases are slightly better e.g. exceptions, the typing used for parametric polymorphism, code size (see when the templates are instantiated) and so on
What I’m basically trying to say is that while C++ has a future in terms of high-performance scientific work, for application development, particularly large scale application development, C# is one of the most promising languages out there.
But unfortunately we won’t be able to use them in 2004 since the release of .NET 2.0 has been pushed back because MS SQL Server “Yukon” is late. The generics implementation itself seems to work just fine as of now and would be ready for an immediate release.
It really is a pity that this nice language feature can not be used just because a completely unrelated technology is late.
So the benefits of C# generics are…
Java generics are precomilation and wrapping native types.
So using reflection on methods reveals no type information for arguments, return values etc. JIT in C# is more efficient for (native types only?) because it doesn’t wrap native types in objects.
C++ doesn’t have enough checking done at compile time, so it has issues with slower development. I’m assuming it also completely lacks reflection functionality?
I’m guessing the performance is still slightly with C++ (doesn’t need to do the JIT step), then C#, then Java.
My conclusions is that not being excited about C# or generics isn’t a big deal. You can still use your favourite language to achieve what you want. C# improvements in this area are only incremental, just scratch one more tiny niggle a programmer “might” have. Not exactly innovative stuff tho.
The benefits of C# generics are huge. Since C# shares the code for all non value-type instantiations of your template, you will have a much smaller working set and a much higher chance that the working set fits into the cache. So I expect that C# generic classes will be much faster than C++ generics.
The Java implementation is so slow as to be irrelevant. For example in a program where you want to count how often each word appears in a text, you would use a hashtable that maps strings to ints like this (C# syntax):
Hashtable<string,int> wordcount=new Hashtable<string,int>();
List words=tokenize(text);
foreach(string word in words)
wordcount[word]++;
Since java represents the values as objects internally and Integer is immutable, there would be boxing and unboxing each time you increase the count for a word. In the C# version you just increment an integer. The performance of the java version will be absolutely horrible, and the C# version will perform close to the theoretical optimum. In the C# version the most expensive operation will be the hashing of the word, while in the java version the creation and garbage collection of the temporary objects will be the most expensive operation.
The problem is that in Java Ingeger instances are immutable.
But this IMHO has nothing to do with generics.
BTW, nobody forbids me to create a Counter class with a some increment by one method and appropiate setter and getter mehods.
Carsten
agreed – in fact, the respected Univeristy of Bristol, UK, don’t teach C++ as its considered such a cludge. (iirc).
That says nothing. A university is not supposed to be a “job training”. Its purpose should be to teach concepts, not tricks. To get the concept of OO across, C++ is not the best language.
In fact, most universities don’t stop at OO – it’s just one of the many paradigms. Most researchers tend to like functional programming instead. Again, this says nothing about “real world usability”.
As an example, they asked a CS prof to teach basic programming to physics and chemistry students at my university. First thing he did was have a good laugh at Fortran, and had all the students learn Java instead.
Needless to say, this was a ridiculous choice. After one year of class, the guy was thanked for his efforts and quickly gotten rid of.
well, C++ could become obsolete if some one would develop an optimised compiler for Java and C#. talk about ultimate flexability, you could have the choice about compiling or running it in a VM….that would be cool.
The thing is that while it is possible to do those things you mentioned in C++, all these features are a core, natural part of the C# language (not a library of any sort) .
You say that as if it’s a good thing. It’s an enormous benefit of C++ that the language offers nothing at its core that you could write as a library instead. It’s the C philosophy, and it’s an important reason C is still around.
Anything that can be written with the language should not be in the language instead.
No, nobody forbids you to write ten times as many lines of code as nessecary for a very trivial problem.
And even if Integer was mutable, there still would be boxing and unboxing for each distinct word since it is stored as an Object in the hashtable entry, while the C# int is stored directly in the hashtable entry. So even if Integer was mutable the java version would create a lot of unnseescary objects and do a lot of boxing/unboxing.
The whole thing gets even more pathetic if you have a list of integers. In C# an ArrayList<int> with 10000000 elements requires two objects on the heap: the ArrayList object itself and the int[] it uses to store its data. In java an ArrayList<int> with 1000000 elements requires 1000002 objects on the heap. The ArrayList itself, the Object[] used to store the references and 1000000 Integer objects.
This creates a huge (~factor 4) memory overhead, completely devastates cache consistency and is a major PITA when these 1000000 unnessecary objects have to be garbage collected.
This example just shows you some of the gems of C++. It’s not going any where anytime soon.
#include <iostream>
template< int N >
class num {
public:
long double factorial() {
num<N-1> pre;
long double f;
f = N * pre.factorial();
std::cout<<N<<” – “<<f<<std::endl;
return f;
}
};
class num<1> {
public:
long double factorial() {
return 1;
}
};
using namespace std;
int main() {
num<1000> my10;
cout<<my10.factorial() << endl;
}
That is abusing the template mechanism to do something it is not made for. The syntax is ugly as hell compared to functional languages which support that kind of stuff intentionally.
You should really take a look at functional programming languages such as clean. They can be just as fast as C++.
That was just a short example to demonstrate it. The formatting is messed up by osnews because there is no <pre> tag support.
In any case it is highly appropriate in this example because no code gets generated to calculate the factorial. It is all done at compile time so the code contains the answer. You have to admit that is neat and efficient for code that runs many times.
Yes, I have to admit that this is efficient. But the syntax is still ugly. With functional programming you can get this just as efficient and beautiful.
How is that different from
double factorial(int n) {
double result = n–;
while(n > 0) {
result *= n–;
}
return result;
}
I don’t see why you’d want to use templates to code a factorial function, much less call that one of the gems of templates.
I agree that the syntax will be better with functional programming but I chalenge anyone to provide an implementation for factorial in any language that is more efficient than this one. It takes no time to calculate remember!
How is that different from
double factorial(int n) {
double result = n–;
while(n > 0) {
result *= n–;
}
return result;
}
Why don’t you compile both versions and time the result? 🙂
I think your code does not have the desired effect, if
there is no inlining. And I don’t know if you want all the functions being instantiated. Here is the common
example:
#include <iostream>
template< int N > class fact {
public:
static const long double result = N * fact< N-1 >::result;
};
template <> class fact<1> {
public:
static const long double result = 1;
};
int main()
{
std::cout<< fact<1000>::result << std::endl;
}
@Wee-Jin Goh: The difference between this construct and your code is, that fact<1000>::result is computed at compile time. At running time it is only a constant. Whereas your code is executed each time the factorial is computed.
Wee-Jin Goh: The trick is that the factorial is computed by the compiler at compile time.
Tuttle: While it is true that this kind of use of the template mechanism was unintended, it’s discovery did open up a whole new programming paradigm for C++ – a paradigm far beyond container-of-T-generics. See A. Alexandrescu ‘Modern C++ Design’.
And about C++ becoming obsolent… Fortran and COBOL have been declared dead decades ago, and yet they are still with us.
So will that result in a larger executable, or longer compile times, or what? Any drawbacks apart from the rather unsightly code?
the only reason will be that the CLR will be loaded when windows boots just like IE and parts of office. this will allow C# apps to have short load times. that will be the only reason since Java and C# apps are both easy and fast to create.
I used –some days ago– the EQUIVALENCE feature of good old FORTRAN 77 to map character strings on integers to process them using the vector units of a vector supercomputer. The regular expression code was a factor 300+ faster afterwards. Nice hack. But, no one but myself was able to understand that piece of code.
A few years later I got the job to make a MPI library thread safe. This library was completely written in C++. Well, it could be compiled with a C++ compiler, but since it contained not a single class an ANSI C89 compiler would have been sufficient. But C++ was hype and thus better for marketing. I started to analyze the code and the result was the lib had to be completely rewritten to make it thread safe.
Looking for a programming paradigm suitable to program concurrent (read multithreaded) systems, I learned to really love object orientation. The benefits of using objects for myself overcompendates such proclaimed factor 4 overheads. I now earn my money with the archtecture for business middleware codes and I mostly deal with virtually infinite compute resources for the given problem. So, far I none of my customers had performance problems. But some deal with 10000+ concurrent users.
Carsten
the problem with functional programming is that, while it is powerful, the Syntax is alien to the way most people think. Imperitive languages are more like natural language, while Functional syntax is more like Mathmatical way of thinking. because of this, you get a steeper learning curve than you would with a language like C (learning the basics of C is super easy and it just takes time to learn all the ways you can accomplish things)
Wee-Jin Goh: Longer compile time; and you require a fairly sophisticated compiler (the major ones pretty much all are by now).
It’s the traditional trade off: you can have fast runtimes, or fast compile times, but usually not both.
: fac 1 swap 1 do i * loop ; 10 fac .
Runs at compile time, instantaneous 😉
“The problem with functional programming is that…the Syntax is alien…”
I tried to read an introductory tutorial for Haskell once, but it was thick with mathematical language and unfair assumtions about the reader. For this reason functional programming remains inaccessable to most people.
I think the main barrier is more semantic than syntactic, though. I believe that thinking of a sequence of commands is more intuitive than evaluating mega-expressions. It is clearer in an imperative language the order in which things happen (although most languages have some sort of expressions which muddies this a bit).
i think one of the main problems with programming today is people become “language zealots” or “gurus” and not engineers. i have worked with to many people that really know a language, but know absolutely nothing about writing clean, consistent interfaces, loose coupling and component independence. in terms of language, my forte is C++, just because most of my work is backend Unix servers, and that is what we use. i learned Java, perl and a few other languages in order to increase my personal “toolbox”. if i had to write a front on to one my servers, most likely i would write it in java, not because of a religious zealotry or anything like that, but it is the right tool for the job in our environment. just like i use perl when i need to text processing of config files and some sys admin work.
i think it would be a lot more productive to focus on the strength and weakness of a language for certain environments and projects, instead of have a blind “all or nothing” allegiance to a language for the sake of…well, i really don’t know why… i have always viewed programming and engineering as the perfect marriage of creativity and analytical thinking, and i do not let political or religious ego get in the way of producing the best systems i can.
If you do vector graphics, complex numbers, numerical computing or anything that has to do with numbers a memory overhead of 4 is relevant. And the C# solution is just as OO as the java solution: System.Int32 extends System.Object, and you get all the benefits of OO such as encapsulation for value types.
The fact that java has no value types is the reason that swing, java2d and java3d are so slow. They handle large amounts of tiny objects (mostly Point and such) which destroys cache consistency and has a huge memory overhead.
If you work in an environment with “virtually infinite computing resources” a factor of 4 is no big deal. But whenever I run a client side java program I notice that I do not have “virtually infinite computing resources”.
The article focuses on the use of templates for generic containers, which is the primary, naive use of them. It does not mention the more modern uses of templates that are available in C++. They are right to say that templates are “just macros”. That’s what makes them powerful : they should be seen as a small ML-type language to use in order to generate your own code.
More modern template uses include type traits, conditions on type parameters (similar to the C# constraints), meta-programming (as demonstrated by an earlier post). The possibility to use integer macro parameters also has a very nice application for using the type-checking system to enforce dimensional consistency in physics (speed = distance / time for example). It is completely false to say that you have one implementation per instance of the template, since specialization, and partial specialization, allow you to share instances and optimization that are common to classes of type such as pointers or arrays.
Function templating allows for CLOS-type object design, which is often very nice.
Can C# do all this ?
I know that there is no silver bullet, but functional programming comes very close.
You can have implicit multithreading without having to deal with low level constructs like locks and semaphores.
The whole value type/reference type problem goes away if your data is strictly read-only.
You can have automated caching of expensive calculations since you know that a function that is called with the same parameters will always have the same result (absence of side effects).
It will take a few more years, but sooner or later pragmatic* functional languages will hopefully find their way into the mainstream.
*pragmatic means that such languages allow side effects in some situations (like Clean) instead of using complicated stuff like monads (like Haskell).
Functional languages like clean are much more productive than both java and C#. I really hope there will be a clean# in the future…
Functional programming paradigms are getting their way into traditional imperative languages. ( Like anonymous functions = lambda forms, lazy evaluation techniques, meta programming like Lisp macros … ).
Yes, FP languages are much more expressive, powerful and secure than traditionnal languages. However, they generally lack user control of ressource allocations (such as data to memory mapping), and side effects that are effectively indispensible for existing computer architectures and many types of applications.
Also, it is a wrong impression that FP languages can represent in a single solution all the possible features of a programming language : just look at the separation between the ML (OCaml, Haskell, FL, …) and the LISP line (CLISP, Scheme R5RS, Bigloo…) to realize that there are lots of disaggreement in the FP world too.
> However, they generally lack user control of ressource
> allocations (such as data to memory mapping), and side
> effects that are effectively indispensible for existing
> computer architectures and many types of applications.
>
Take a look at uniqueness typing in clean. It gives you a way to have side effects and all that that fits very nicely into the FP paradigm. One of the first things I tried with uniqueness typing was to write an in-place quicksort. It requires a bit of care, but it is just as fast as optimized C while still preserving the advantages of FP.
The fact that java has no value types is the reason that swing, java2d and java3d are so slow. They handle large amounts of tiny objects (mostly Point and such) which destroys cache consistency and has a huge memory overhead.
Actually this problem could also be solved in java if they were to either
A: Force the programmer to create their own instances of objects instead of returning new ones every time. For example, the code for figuring out the layout of a container requires the creation of n Dimension Objects, where N is the number of sub components below a panel. If the programmer was required to create an instance and pass that in, then that instance would be used and filled with the proper values, then it could be much faster then creating n objects all the time.
B: Force Point, Rectangle and Dimension classes to be immutable. You could then use a factory method to get your instances and the most common instances could be cached, thus you would save on memory and creation time.
Both these require API changes however and could never be done. Even though object creation time is much faster then it used to be, it’s still a bottle neck and should be minimized.
Using object pools for trivial objects such as Point and Rectangle would lessen the problem somewhat, but the memory overhead and the cache consistency issues of millions of tiny objects all over the heap instead of a continuous array would still be there.
And it would be a major pain to implement and use this compared to the simplicity of real value types.
Its not so much the syntax as the semantics. The syntax is pretty normal —
(format-out t “hello”)
isn’t really any-less easy to understand than
printf(“hello”)
The first is prefix syntax, and the second is infix syntax. Both are imperative, and IMHO, equally easy to understand. Now, in a pure functional language, you’d have to do that I/O through a monad, which makes things more complicated.
The nice thing about prefix syntax in particular is that it allows for procedural macros to be implemented very easily, which makes it much less necessary to build new features into the language itself. People have yet to come up with a macro language thats as easy and powerful for infix-syntax languages, though Dylan’s macros come close. Its interesting to note that C++ has something of a very elementary macro language — the template engine. If the metafunctions proposal makes it into C++ 0x, even more programmers may be introduced to macros.
I think you bring up a very good point of C++’s template engine. Its implementation of generics is quite powerful and sort of unique among programming languages. Even Lisp really doesn’t have something comparable, nor does ML. The closest I’ve seen is some of the features in Cecil, or some proposals for Goo. What I’d like to see done to types is what continuations did to control-flow. With continuations, you can achieve any given type of control-flow — threads, co-routines, exceptions, etc. I’d like to see a similar feature that would encompass and unify polymorphic multimethods, subtyping, and generics. I don’t have the foggiest idea what form that would take, though.
I think you bring up a very good point of C++’s template engine. Its implementation of generics is quite powerful and sort of unique among programming languages. Even Lisp really doesn’t have something comparable, nor does ML. The closest I’ve seen is some of the features in Cecil, or some proposals for Goo. What I’d like to see done to types is what continuations did to control-flow. With continuations, you can achieve any given type of control-flow — threads, co-routines, exceptions, etc. I’d like to see a similar feature that would encompass and unify polymorphic multimethods, subtyping, and generics. I don’t have the foggiest idea what form that would take, though.
What I’m basically trying to say is that while C++ has a future in terms of high-performance scientific work, for application development, particularly large scale application development, C# is one of the most promising languages out there.
I’ve never seen C++ used in any of the scientific applications we use. Virtually all the scientific programs we use are written in Fortran, with some others such as the model output viewer being written in Java. Fortran has a very rich mathematical syntax compared to C/C++ [i.e. ** vs exp()] and consequently there is considerably more room for compiler optimization compared to languages where mathematical functions aren’t part of the syntax.
Using object pools for trivial objects such as Point and Rectangle would lessen the problem somewhat, but the memory overhead and the cache consistency issues of millions of tiny objects all over the heap instead of a continuous array would still be there.
And it would be a major pain to implement and use this compared to the simplicity of real value types.
True, I know what you are saying with respect to Arrays, and in many cases, it would be better if you could just do that instead of having to create the array seperate from the object.
Value types are a nice optimization. However, isn’t one of the first tennents of good programming to not optimize too early? If you start using value type all over the place and later you determine that you actually need classes then are you not painting yourself into a corner?
Value types are good when you know that data will not need to change, because structs are final ( cannot be subclassed). Thus to ‘extend’ a struct you are going to have to wrap a lot of code, or copy structs, or do other acky things (just like in Java). Though this is not unlike the situation in Java when you have final classes, final classes are generally not used except when data must be protected.
Value types are good in ‘real life programming’ which C# seems to be heading twords. I think that MS will make many optimizations to ensue that it runs better then Java or any other VM based language. It seems like to me that they are not using the VM to actually abstract the hardware from the software, but rather as a default toolkit that all languages can share. So that it makes it easier to write code in any language and they can all talk to each other rather then the hacks that we have today.
This is definitly a win for MS, and if they actually achieve this goal of cross language and cross version compatability, then they will have achieved their goals. I think that .NET goes much further then ‘trying to kill java’ as so many have assumed. Java is not the real enemy for MS, but rather their old code, that people are still using and struggling with.
> Value types are a nice optimization. However, isn’t one of
> the first tennents of good programming to not optimize too
> early? If you start using value type all over the place and
> later you determine that you actually need classes then are
> you not painting yourself into a corner?
>
Yes indeed. And that is why you should only use value types when the thing you want to write benefits from value semantics or if performance is extremely critical. In the case of complex numbers and vectors it is very straightforward to see that you want value semantics.
When I will teach newbies to program in C#, I will certainly not tell them about how to define value types until very late in the course, if at all. You can use C# prodctively without ever defining your own value types, but as a class library designer it is very useful to have that option.
Value types are completely unnecessary as an optimization.
http://citeseer.nj.nec.com/rd/0,109355,1,0.25,Download/