this node tries to separate the truth from the vaporware and the FUD (fear, uncertainty and doubt).

It is difficult to know where to begin in pointing out the misconceptions in the above writeup, so I will attempt to address each of the points in turn.

Both Java and C# are 4th generation languages

Neither Java nor C# are 4GLs. The distinction between third and fourth generation languages is that in a 3GL, the steps required to achieve a result are specified in the program, and these result in the desired output, whereas in a 4GL, the desired output is described, but not the steps taken to derive it. The actual sequence of operations performed is generated by the language's runtime. A good example of this is SQL. An SQL SELECT statement describes the conditions that a row in a table must satisfy to form part of a set. Before SQL can be executed, the parser must generate a query plan which is the steps taken to scan tables, make comparisons, perform sorts, etc, to produce the set.

To give an example, a 3GL recipe book would list ingredients and instructions, whereas a 4GL recipe book would describe the appearance and other attributes of the finished meal, but leave it up to the chef to work out how to get there. A 3GL book is easy to use for the chef, because the author does most of the work. A 4GL recipe book, in contrast, is designed to minimize the work done by the author. In this example, the author represents the programmer and the chef the computer.

Java and C# are both 3rd-generation object-oriented languages.

These languages are typically used for advanced "enterprise applications"

There is nothing in Java or C# that makes them particularly suited for "enterprise applications" as opposed to any other large scale software project. A language that is specifically designed for enterprise applications is SAP's ABAP and BASIS environment, or Borland's Delphi. Java and C# are both object-oriented, which makes them suitable for many complex software engineering tasks. Java originated as an embedded systems language, and C# as an enhanced object-oriented C/C++ replacement. C and C++ are both general purpose programming languages.

These are highly specialized applications that are generally developed "in-house" (each company develops it's own) and are not typically sold like regular software (in a box, with a manual)

Tell that to SAP, Oracle, PeopleSoft, Redbrick, SAS Institute, JD Edwards, Baan, Siebel Systems, Kana and any of the dozens of other vendors who sell packaged software for CRM, ERP, SCM, DS etc.

Java and C# by themselves are more or less useless. Because of the high degree of abstractisarion used, they both relay on a set of applications and libraries that connect the language to the OS (operating system) and different data sources (databases, directories, etc.).

On the contrary, the languages and their runtimes are synonymous, just as C binaries and libc are. Almost every language is reliant on libraries and underlying OS services, this is by no means a unique property of Java or C#. It is common to write useful programs that are not reliant on third-party external data sources in any language. For example, there are many applications that read their data from a simple text file, perform some processing, and write out another text file.

As far as performance is concerned, both Java and C# are too slow to be used in games or most "regular" applications, they are designed to be used for "n-tier systems".

This was certainly true in the early days, but recent benchmarking by IBM places JVMs with JIT to be almost as fast, and in some cases faster than native code. How can an interpreted language be faster than a native binary? Because a compiled language cannot take into account the execution paths of the software at runtime, whereas a JIT compiler can observe the software executing and target its optimizations where they will yield the most improvement, trading, for example, memory for speed. These techniques were popularized by DEC's FX!32 technology.

It is also true that both Java and C# are designed to be used for distributed applications. J2EE with EJB and .NET are both network-transparent; invoking a method in an object can be done irrespective of where that object is physically executing. This, however, is not the same as n-tier, which is a process of abstraction separating presentation, data, and logic. The tiers may be web browser, web server, application server and database, but this is only one example. It is not the specific components that matter; rather it is the logical design (for example, all tiers could physically be implemented on the same physical device without compromising the n-tier design). An n-tier design can be implemented in almost any programming language. A distributed application is not inherently n-tier.

What .NET lacks is wide industry support.

There are 3 million VB programmers in the world with an almost seamless migration path to .NET. Java had limited support in 1995 but C and C++ programmers easily migrated to it; C# is easily adopted by anyone familiar with Java, C or C++. In addition, .NET's CLR, the underlying runtime environment analogous to Java's JVM, is language-neutral, .NET applications can be written in C#, VB.NET, C++ or even exotic languages like Eiffel.

C# has some added programming features like pointers and operator overloading, that have been removed from Java because they were considered as problem-makers and obsolete, even in 1995. Overall, C# presents some improvement in code style and syntax but most differences are not missed while working with Java.

That's a very subjective argument. Take a bug that is frequent in C and Java: if (a = 5) { doStuff(); }. This will compile and execute in Java, but will be caught at compile time by C# (the bug is = instead of ==). And pointers are very useful; modern high-performance rendering software would be impossible without function pointers. It is widely believed that features such as multiple inheritance were omitted from Java to simplify the implementation of the JVM, rather than as is often claimed, because these features aren't used by developers. Certainly my own experience is that implementing interfaces in Java means sacrificing OO benefits like inheritance and subsequent overloading of methods, particularly when invoking a superclass within an override. The fragile superclass is not a problem on modern hardware, since compilation is much cheaper.

This raises the issues: how does Microsoft expect to have success with its new platform, a totally proprietary system, while most companies are looking for open software that enabled growth and cost reduction, without locking you into a certain vendor's software?

C# and the CLR are ECMA standards; Java is wholly controlled by a single vendor, Sun, who retain sole privilege of certifying software as fully compatible, for a rather expensive fee. See http://msdn.microsoft.com/net/ecma/.

On the other end of the spectrum, Microsoft's .NET lacks any open source, or even free, implementation. A linux company, called Ximian, is working on porting the C# language to Unixes but it won't be able to implement some vital parts of the .NET platform, greatly reducing the overall usability of the software.

I will assume this is an innocent oversight, but the source code to a full .NET development environment for FreeBSD and Win32 is freely available for download. See http://msdn.microsoft.com/net/sscli/.

Microsoft's solution brings insignificant performance and style improvements over current systems, and the lack of Java-to-C# porting tools will turn the transition from a platform to another into a full blown application rewrite, even if the languages are similar.

Again I will assume this is an innocent oversight, but see http://msdn.microsoft.com/vstudio/downloads/jlca/default.asp. There is a much clearer migration patch from existing Win32/COM/DCOM code to .NET than there is to J2EE. The benefits of a near-native object model (DCOM/COM+) give great performance enhancements in C# compared to IDL-binding CORBA to Java, and it has yet to be proved that JNDI offers superior performance to Active Directory. Certainly the X.500/LDAP vs NDIS argument favors the latter for performance.

Java has become very portable, running from cell phones (J2 Micro Edition), to desktops (J2 Standard Edition), large servers and even old COBOL mainframes (J2 Enterprise Edition). Meanwhile C# binds the programmers to a single OS, Windows, a single IDE, Visual Studio and a single architecture, IBM-PC (Windows runs on Intel x86, IA64 or old and obsolete Alphas).

There is nothing to prevent CLR running on a non-Wintel platform; the standard is open, it's merely a matter of time for it to be implemented. As pointed out, it already has been for FreeBSD on x86. As DCOM was ported to Linux by Software AG with Microsoft's full support, there is no reason to suggest that the CLR will not also be ported to many platforms. The C# tools are not bound to a single IDE (I personally write C# with Xemacs and GNU Make). Further, Windows CE runs on many CPU architectures. (Incidentally, NT used to be supported in x86, i860, PPC, Alpha, MIPS and SPARC, all but x86 were dropped because people weren't buying on other platforms, hardly Microsoft's fault).

J2EE will happily run on a desktop; the difference between Standard and Enterprise is not a function of the underlying hardware or OS. Java is meant to be platform-neutral, remember? And how can it be a COBOL mainframe if it is, as you say, running Java?

I hope the writeup has gone some way to clearing up the FUD in this node. The original writeup in the node verges on propaganda, and includes many factual errors which happen to support the author's clear personal preference for Java. In truth, choosing a language depends more on the existing skills of the team, and the existing software within the organization, rather than novel features of a single language.


Response to irexe:

Indeed; I was merely pointing out one of the lies^H^H^H^Hmisconceptions in the original wu.