In my new job, which will start on the 1st of February, i will first work in c++, and then be moving on to .NET. This was not entirely what i had in mind. I was planning on moving to java, completely. On such short term though, this seemed difficult, because up until now i haven't had much real experience with java. Although, pure java programming, coming from c++ is very straightforward. But i am unfamiliar with the standard libraries. Even worse, making the leap bigger, i am definitely unfamiliar with the J2EE framework, and all possible frameworks available to make your life easier (struts/spring/hibernate..).
When switching to java, the problem no longer is learning the programming language, but getting to know all the available frameworks. And it is a big leap. As a former Sinclair QL adept, i would say Quantum Leap ;-)
But the advantage of java is that is more open source. Almost everything is freely available, or you can find good "free" alternatives. There are no ties to specific platforms, or suppliers.
That is exactly what scares me about .NET. But looking at it in more detail, it is actually pretty neat. It is designed, mind you, by the guy from Borland, Anders Hejlsberg. My god, Borland ! I am a Borland fan from the start, precisely because of this guy, and because of their war against Microsoft. Well war is not exactly the right word, but i always had the impression Borland was the underdog, with a superior product. Speaking of VCL, Delphi or C++ Builder : it always was a better language than VB, and a great RAD-tool. Visual C++ had its strengths though. Definitely. It was a very impressive compiler, but not RAD. Microsoft made this weird decision that VB would be the RAD-part, and Visual C++ would be for real programmers. For instance, making a make-file in Visual C++ was and still is way better than in Borland C++ Builder. In Visual C++ you can keep different targets, which is very handy.
By the way, does anybody remember what RAD stands for ? Rapid Application Development. Nowadays it would be called agile ;-)
Anyway, i was looking at Java 1.5, with generics, which i was looking forward to, as it is one of the strongpoints in c++, imho. Anyway, in java it is not at all implemented well. An ArrayList still remains an ArrayList on the inside, because Sun didn't want to adapt the JVM. So all translations are done in bytecode. All casts are inserted. An ArrayList will be converted to Objects, so you lose a possible efficiency advantage. Reflection will not work, because from runtime on, it is just a normal ArrayList. Imo this also means you can still insert other types into an ArrayList. Doh!
In c#, generics are done well, but, alas, different than in c++. At least an
ArrayList<int> can only contain integers. That's a relief. But in c# the typing is much stronger than in c++. And I am not quite sure whether this is better or worse. In an age where everyone is pointing at Ruby, and its weak typing, and it's apparent advantages, c# goes to the extremely strong typing.
Let me explain. In c++, templates are a kind of macro, which get instantiated at compile-time with a type
<t>. This means, that in the template you could use any function, and only at compile-time, will it check whether such a function is available. Whereas in c#, the generic is a real class, and you have to define the constraints on the type, or the class wont compile. Meaning you have to specify the interfaces
T implements, for instance, or which classes it inherits from. Which is ok, it is much stricter, it is correct, and it will catch bugs much earlier.
Whereas in c++ you could get this weird, unreadable, lengthy errors, when instantiating a template, and some function suddenly was missing. A classic are the comparison operators (well, at least in my experience). It is a design decision of course. I am not quite sure which exactly is the best. Introducing a possibility of weak typing does sound appealing, but also has disadvantages.
As in Ruby, where typing is very weak: if it walks like a chicken, and talks like a chicken, it must be a chicken. In Ruby, all checking is at runtime, it is never type-based, but signature-based. So if a specific class has a certain expected function, doesn't matter which type it has, or where it derives from, but if the function is available and the signature matches, call it. Great. This ultimately is very dynamic, and possibly very strong. It also invites, of course, as always, possibly bad programming. And you will have to use unit-tests very thoroughly to catch all errors soon enough. But it sounds great.
I am going to try out Ruby (and RoR of course), and I will keep you posted.