Hacker News new | past | comments | ask | show | jobs | submit login
What factors led to the development of C# in spite of Java (stackoverflow.com)
44 points by ashishgandhi on June 25, 2012 | hide | past | favorite | 72 comments



Fundamentally, Java and C# are extremely similar. What's interesting is how different their philosophies are: Java really values backwards compatibility, does not evolve very fast and tries to hide and features that could cause a programmer to shoot himself in the foot. C#, on the other hand, has had some compatibility breaking changes, has evolved quickly with fancy research features (e.g. Linq is actually much like a monad with SelectMany as bind) and has a bunch of "dangerous" features like operator overloading and unsafe regions.

EDIT: Maybe there weren't actually any language changes breaking backwards compatibility. I'm not sure.

I personally like C#'s philosophy better: PL research exists for a reason and newer features make coding easier; moreover, I can avoid doing really stupid things and so can be trusted with operator overloading! Others maintain the opposite and believe Java's more conservative approach is best.

It would be nice to compare how the two philosophies fare in getting their respective languages adapted, but I fear such a comparison would be flawed: C# is much too tied to Microsoft, so most people not keen on heavy coupling with any particular vendor or OS tend to avoid it for that reason. The opposite is also true: heavy MS shops are much more likely to choose C# just because it's part of .NET, and not because of the language characteristics.

Still, it is very interesting to see what has happened given two virtually identical languages with different backers and philosophies.


     [Java] does not evolve very fast
While this is true for Java the language, it's not true for Java the VM, which evolved a lot faster than the CLR.

And because Java the language does not evolve very fast, the ecosystem has given birth to mature JVM compilers/interpreters for languages such as Clojure, Scala, JRuby and Groovy, amongst others.

The biggest difference between Java and .NET is that the "backers" of Java come from a really big and open-source friendly community.


For most part of the programming world, Java is synonymous with, Java the programming language, not JVM.

I always thought Java went very heavy on the frameworks side. Evolution was faster on the frameworks end.


I think it's irrelevant what people associate Java with, as long as its success can be attributed partly to the awesomeness of the JVM. There's no other mainstream VM out there that does the optimizations that the JVM is doing, or that has the awesome garbage collectors that the JVM has.

Have you seen the details of the new Java G1 garbage collector or the specs for JSR-292 (InvokeDynamic)? That's awesome evolution right there.


I am not saying JVM isn't awesome. But JVM isn't anymore about Java, than JavaScript is about Java.

Its like calling the Pentium/AMD/ARM as C processing Machines.

The name is deceptive, JVM based languages gives an impression that the languages have to do some thing with Java. Sure they have Java interoperability, but that is different to liking them them with the 'Java programming language' brand. Since JVM was shipped to run Java programs, it was called Java virtual machine.

Otherwise its a virtual machine optimized to run Java programs. When people think of Java its 'Java the language'.

JVM improvements are not necessarily improvement on the Java programming language syntax and semantics.


Well, .NET does have stuff like Iron{Ruby, Python, Whatever}. It also has F#, which is awesome, and VB, which isn't.

Also, Java is now backed by Oracle which isn't the most friendly of open source companies either.

However, I was actually only really talking about Java the language and not the JVM.


Not to be negative here, but compare JRuby with IronRuby ... while IronRuby is basically unusable and almost dead, JRuby is not only really mature, but also the fastest Ruby implementation available. A lot of Ruby apps are right now deployed on top of Java servlet containers. There's practically no comparison to be made.

The only alternative language for .NET that's worth talking about is F#. But it's interesting to note that F# is sponsored and developed by Microsoft, while a language like Scala came from a third-party community. This is important because Microsoft is known to just dump projects that aren't generating a good return on investment.

     Java is now backed by Oracle which isn't the most friendly
     of open source companies either
Java was always backed by a huge community that includes IBM, Google, Intel, Red Hat, Novell and the Apache Foundation. The recent lawsuit against Google only goes to show that the genie is out of the bottle.


Actually Nemerle is a language worth talking about. What those guys are doing is brilliant. I remember even years ago - playing with the language - I was able to embed a natural syntax for a constraint programming library, encode a clean syntax on top of/for phantom types and write a monad system with transformers (via the macro system - think Lisp not C). This was back before Monads were cool in the regular community but very old hat in the haskell community.

What they are doing with version 2 is even more impressive and they are now sponsored by JetBrains.

F# is an excellent language* if you are doing Windows programming right now, you would be doing yourself a disservice not to look at it due to preoptimized worries. The language source is available , hacked on and ahead of Microsoft's version in certain aspects. In the case of a dumping, the community is talented and F# generates IL, unless C# is abandoned there is really nothing to worry about.

* I'm experimenting with intelligent, data based programming with a mix of Steffen Forkmann's JSON schema inference + ConceptNet + custom query syntax + embedded prolog + machine learning.


"unless C# is abandoned there is really nothing to worry about."

Hasn't Microsoft abandoned C# for internal development?


No. There was some FUD that because they didn't do things like rewriting Office in C# they weren't committed. Because rewriting 100 million lines of C++ just to prove a point would be such a good investment in time.


Major Products written substantially in C#:

SharePoint Visual Studio 2010 The C# compiler is being rewritten in C# Microsoft Dynamics


> it's not true for Java the VM, which evolved a lot faster than the CLR.

I'm curious as to what you mean by this; what part of the Java VM has evolved faster?


Compare the choice of garbage collectors and high performance JVM implementations vs what the CLR offers. I don't have recent benchmarks for the MS implementation of the CLR, but Mono lags noticeably behind Java in terms of performance: http://shootout.alioth.debian.org/u64q/benchmark.php?test=al...


Mono is a completely different implementation from the CLR. I wouldn't be so quick to discount the CLR's GC.


I find it interesting that when folks want to claim that .NET is crossplatform they cite Mono, but when performance is discussed they are only prepared to discuss the performance of the MS Windows implementation provided by MS. The last time I benchmarked .NET (on Windows) it was significantly slower than java (with -server flag), but their EULA forbid publishing benchmark results at the time (was a long time ago, but since the parent is discussing .NET v1.0 and it's creation...)


Microsoft disallows .NET benchmarks. If you want to compare Java and .NET you have to have their approval first.


Can you cite that? It sounds like an odd thing to do/suggest. I'm not even sure how Microsoft would stop people even if they wanted to...


I was wrong, they changed the EULA in the meantime.

Here are the conditions I could find (you still have to comply with those conditions, but it's doable): http://msdn.microsoft.com/en-us/library/ms973265.aspx

And they can stop you through the EULA .NET gets distributed under, because no other license gives you the right to use .NET, so you have to do it under the terms of that license.


The MS CLR is also significantly slower than Java: http://shootout.alioth.debian.org/demo/benchmark.php?test=al...


The situation is a bit more complicated than that.

To begin with, there are basically three CLR backends with sufficient maturity: Microsoft.NET, Mono, and Mono/LLVM, of which Mono is probably the slowest, because it is optimized for fast startup; that is matched against java -server, which (unlike -client) does extra optimizations (like mono --llvm) at the expense of a slower startup time. This works for short benchmarks, because compilation time is fairly minimal for these tight-inner-loop benchmarks.

Second, none of these benchmarks really touch on any of the JVM's weak spots. The classical example here is complex number arithmetic, where even an addition can potentially trigger a heap allocation (the JVM escape analysis only helps as long as functions don't actually store results anywhere). There are unfortunately quite a few such features where you get extra overhead to implement the workarounds.

Third, the JVM tends to be a bit of a memory guzzler. Combined with java -server's fixed-size heap, that can create problems in some scenarios (such as a system process that forks a few instances of itself).

In the end, few people will pick one or the other for the raw performance (which, in the end, is not very far apart), but for the ecosystem that comes with each backend.

It is worth noting that there are also other VM-related concerns, and overall, the CLR has the superior design as a general-purpose language backend.

For example, CLR functionality is a superset of JVM functionality. That makes the CLR far more pleasant to use as a compiler backend than the JVM (the reason why JVM-based languages use the JVM primarily is probably to hook into the JVM ecosystem, not because they love devising workarounds to implement closures or value types somewhat efficiently).

Similarly, P/Invoke is in practically all aspects superior to JNI. If you need to call native code a lot, P/Invoke is almost always the easier way to do it.

Library versioning is another issue where the CLR has the better story.

Again, what will almost certainly drive the use of one or the other for 99% of all programmers is what infrastructure (frameworks, libraries) they need. If they want to develop web applications using Scala/Lift, the JVM it is. If you want to implement games using Unity, you're going to use the CLR. The benefits you get from reusing code will almost certainly dwarf other concerns.


>>Mono/LLVM<< What a pain! -- "configure: error: Compiling with stock LLVM is not supported, please use the Mono LLVM repo at https://github.com/mono/llvm, with the GIT branch which matches this version of mono, i.e. 'mono-2-10' for Mono 2.10."


Not to mention that an out of the box .NET/CLR will just run fairly well. An out of the box JVM may or may choke, depending on the app you're trying to deploy. I've spent so much time trying to tune our JVMs for performance, that sometimes it's nice just to deploy a C# app on the CLR and have it just "work".


>>matched against java -server, which (unlike -client) does extra optimizations<< FWIW On a quad-core machine -server is the default.


      That makes the CLR far more pleasant to use as a 
      compiler backend than the JVM (the reason why 
      JVM-based languages use the JVM primarily is probably 
      to hook into the JVM ecosystem, not because they love
      devising workarounds to implement closures or value 
      types somewhat efficiently).
That's not true.

The JVM has inherent advantages that the CLR does not have ...

(1) the JVM can inline virtual method calls and with some machinery attached (bytecode manipulation) you can get pretty close to zero overhead when invoking functions dynamically (the reason for why dynamic languages on top of the JVM have been pretty awesome)

On implementing closures efficiently ... you should check your facts, because delegate invocation on top of .NET always has overhead compared to plain method invocation, while on top of the JVM you can make it so that those invocations will be inlined at runtime (in server mode the JVM even inlines method calls made through plain reflection, which is considered extremely expensive).

Implementations such as JRuby successfully do this, but because of JRuby's nature, the call-stack sometimes gets too tall, beyond the capabilities of the JVM to inline, however this is addressed with the InvokeDynamic support from JDK 7, which will make dynamic method calls as efficient as normal calls.

Because the CLR is not capable of such optimizations, compiler authors have to do a lot of optimizations ahead-of-time, while on the JVM even a dumb compiler can produce good results ... for proof, compile 2 binaries from the same source-code, one with the Mono compiler, the other one with the official compiler, then run on the same platform and compare.

(2) compiler writers love the Jar/.class formats, being really easy to produce binaries for Java, coupled with the maturity of libraries such as ASM ... contrast this with the CLR .dll format, for which the .pdb format for attaching debugging symbols is proprietary and NOT documented, which pushed the people working on Mono to come up with their own format (.mdb). Of course, through reverse engineering and through some code that Microsoft published, the interoperability of Mono with .pdb has improved lately, but it's still painful.

(3) there are many tools available for the JVM that complement compiler authors, tools like ObjectWeb's ASM, which have poor substitutes for .NET. And if you want a good parser generator, there are plenty to choose from for Java, while for .NET the only reasonable choice being Antlr, which is primarily a Java tool that also supports .NET -- on the other hand if you wanted to express your grammar with PEGs I personally couldn't find an option for .NET, while there are several available for the JVM.

(4) the features in .NET that are not used in C# have received poor support. For instance tail calls were NOT guaranteed to be eliminated, even if you specified this behavior in the compiled bytecode. But more than this, tail-calls have severe overhead over plain method calls. And did I mention that tail-call optimizations, as produced by the F# compiler, simply won't work reliably on Mono?

On value types, this is not such a huge issue as many people think. In Scala there's the proposal SIP 15 (value classes) which are implemented in the latest Scala 2.10 milestone release. This will open the door to much needed primitives, like unsigned ints: http://docs.scala-lang.org/sips/pending/value-classes.html

Also, you're making a mistake if you think the CLR type system doesn't have flaws. For instance the CLR lacks a Union type, which makes it a bitch to implement lazy languages, such as Haskell.

The CLR also lacks anything that would aid in implementing continuation-passing-style. The JVM doesn't have anything for it either, however for the JVM exceptions can be used for unwinding the call-stack efficiently and compared with the CLR, exceptions on the JVM are very, very cheap.

This coupled with bytecode manipulation and library authors have been able to build libraries that make use of CPS efficiently.

(5) P/Invoke is basically JNA ... https://github.com/twall/jna

C# does make it easier because it has a couple of primitives that make the marshaling of data easier.


First of all, let's clear some things up so we don't talk in circles. :)

Picking either the JVM or the CLR as your compiler backend is generally done because you either want (1) to hook into the respective infrastructure, (2) want a mature GC technology without having to develop your own, (3) need to generate reasonably fast code at runtime, or (4) all of the above. Most likely, it's a combination of (1) and (2).

If not, you're probably better off picking a more flexible backend that does not limit your object model or (if you're doing concurrency) your memory model. In short, either the JVM or the CLR forces you to compromise when emitting code.

In particular, both the JVM and the CLR are hostile environments for functional languages; if you're compiling a functional language to either (instead of, say, LLVM or MLRISC), you're almost certainly doing it for the JVM ecosystem, i.e. interoperability, vendor support, availability of tools, and such, not because it is a great fit for your needs.

So, when most of your points are about the superiority of the JVM ecosystem, I'm not disagreeing at all.

What I am still maintaining is that the CLR has the superior design. And yes, I am painfully aware of its limitations, too. Superiority is relative, not absolute.

All that said, there are a few of your points that merit a specific response.

(1) First of all, virtual call optimization (not just inlining) is something that the JVM does to solve what is primarily a JVM-specific problem. Simply put, while the CLR allows you to emit both call and callvirt instructions, the JVM has only invokevirtual (invokespecial, which was originally called invokenonvirtual, is more limited). The only option to tell the JVM that a call is non-virtual is to target a final method, which may require code duplication.

Second, nothing in Ecma 335 prohibits virtual call inlining when it can be proven to be safe. I don't know why Microsoft .NET/Mono still don't do it, but I suspect that they just don't see a big need for it, given that C# (unlike Java) uses non-virtual methods by default, and compilers for other languages with different semantics (e.g., Eiffel) can emit non-virtual calls at non-polymorphic call sites if they need to. Virtual call optimization could still be useful for inter-assembly calls (where the target assembly isn't strong-named), but that's probably a rare enough case that it's not certain whether the overhead is justified.

(2)/(3) Generating DLLs is pretty straightforward with ILASM or Mono.Cecil. Including debug information. You can only generate .mdb information on Windows, but then you only need it on Windows, too.

(4) The Ecma standard actually does make tail call elimination not optional for non-virtual calls. "CLI implementations are required to honor tail. call requests where caller and callee methods can be statically determined to lie in the same assembly; and where the caller is not in a synchronized region; and where caller and callee satisfy all conditions listed in the 'Verifiability' rules below."

With respect to value types, you probably misunderstood me. SIP-15 is about adding a layer of abstraction around existing value types. That's valuable, but it's also largely a compiler frontend, not backend issue.

What I was referring to was that the JVM makes heap allocations for tuple types all but necessary, especially if you're looking at collections of tuples. Sometimes you can work around it (such as mapping an array of N complex numbers to an array of 2*N real numbers) if you don't mind the extra work, but just as often that's not easily possible.


Just wanted to say thank you for this great list!


> And because Java the language does not evolve very fast, the ecosystem has given birth to mature JVM compilers/interpreters for languages such as Clojure, Scala, JRuby and Groovy, amongst others.

Most of those examples you gave (i.e. Clojure, Scala, JRuby) also have CLR versions.


...And most of the examples you give are more mature on the JVM and most developers in these languages target the JVM exclusively.


I'm curious: What are the breakages in backwards compatibility that C# introduced?

The only one I can think of is the upcoming change in closure semantics for loop variables - something that is being changed to make it work like people would expect for 99% of the case and risks breaking that 1% of cases where someone actually wants the same loop variable to be closed over in all functions defined within the loop.

(e.g. Linq is actually much like a monad with SelectMany as bind)

Correct me if I'm wrong but I believe, with SelectMany, Linq does in fact, provide everything required to support monads.

Agree with everything else you said - especially on flawed comparisons between the two languages.


The biggest breaking change was from version 1 to 2. Generics were added, as were partial classes, private setters on properties, and delegates. Along the way a lot of little breaking changes were also taken on. Things that change the behavior of the language enough to warrant calling out the incompatibility from previous versions (if you happened to rely on a particular behavior) but which generally result in an improvement in the language.


Did generics break working code?

I didn't think that was possible.


Not easily. There are a few rare instances where they could cause an error during compilation of code that compiled fine for .net 1.1, and some problems with using tlbimp. I don't think it caused previously compiled code to break though.


I don't think there was much backwards compatibility breaks, but in generics C# broke forward compatibility of the bytecode, whereas Java didn't (they used type erasure for their generics).

With that said, C# almost always breaks forward compatibility. It seems like a somewhat odd design goal to have for a language nowadays.


I'm sure you probably know this but that kind of breaking change (to the degree that we can agree that it even exists) is not a C# breaking change since generics aren't a purely-language-feature the way they are in Java. I don't have the C# spec handy but I'm pretty sure that it doesnt prescribe that generics are reified.


I'm not actually intimately familiar with C#. I remember reading about some of the changes between major .NET version (e.g. 2 to 3) which did not maintain backwards compatibility. However, on review, that may have been backwards compatibility of the bytecode rather than the language proper, in which case I am mistaken.

It would be great if somebody who knows one way or the other for sure chimed in.


C#3 adds features not found in C#2 (just as C#2 added features not found in C#1).

However the C# compiler will produce bytecode compatible with the .NET 2.0 runtime from C#3-code. And all C#2 code will compile just fine with the C#3 compiler.

Basically what breaks is trying to shove C#3 code through a C# 2 compiler, and that can hardly be said to surprise anyone.

The part which may be confusing is that unlike Java and the JVM, C# is tied to CLR runtimes, and you can have several installed at the same time.

C#1 was tied to the .NET 1.x runtime. C#2 was tied to the .NET 2.x runtime (which also powered .NET 3.0 and .NET 3.5). C#3 was tied to the .NET 2.x runtime with some extra LInQ DLLs installed (aka .NET 3.5). C#4 (which again adds more features) depends on the .NET 4.x runtime. And all these runtimes can be installed at the same time.

The fact that Microsoft is willing to "leave old runtimes behind" and create new ones when the language features being requested requires it means they can iterate much faster than the Java can, since backwards bytecode compatibility is not required.

I think it is a decision which has worked out largely to their advantage.


The breaking changes are usually minor and side-effects of the other language changes. For example, IEnumerable<T> was made covariant in .Net 4.0. Consider what happened to code passing an IEnumerable<List<int>> to a method with two overloads taking IEnumerable<Object> and Object respectively.


Interestingly, named parameters introduced a kind of breaking change:

http://blogs.msdn.com/b/ericlippert/archive/2011/11/07/break...


The only major breakage has not been in the language, but in the .NET framework libraries; and then mostly in ASP.NET. Between 1.1 and 2.0, quite a few things broke there. Upgrading was no fun at all.


There's no big mystery. I was there and saw it all happen. Java, the language, hadn't made any progress for several years. Programmers like me would complain at Java user group meetings here in Silicon Valley that we wanted certain features in Java (enums, lightweight structs, etc.) and the Java guys from Sun would always do an Apple on us: you don't know what you want. You're not experts; we are. We know what you really need better than you do, because we're smarter than you and have better taste, so trust us, you don't really need <whatever features we were asking for>.

There was always a Microsoft rep at those Java user group meetings. After the meeting, he would come up to us and ask us again what we wanted and why. Unlike anyone from Sun, he'd ask good questions, listen carefully, and take notes.

Microsoft genuinely liked the language as a much-better C++, but wanted it to have native extensions on Windows for two reasons: 1) it would encourage the writing of code that would be less portable, thereby reducing the threat to MS's advantage of being the platform with the most apps, and 2) apps written in "pure" Java just weren't as good as native apps, and for Java to become the "better C++" that many programmers inside MS were hoping for (for their own use), it was becoming clear they would need native extensions.

MS tried to produce a Java with native extensions: Visual J++. Sun filed suit, claiming that MS was in violation of contract. I don't recall the outcome of the suit, because MS decided that Java's slowing acceptance as a general-purpose language for client-side apps (and part of that slowness was CAUSED by MS) meant that there was less need to claim support for Java. It wasn't going to take over the world after all. (Steve Jobs later made the same decision). Not supporting it wouldn't mean you would be left behind. They abandoned Visual J++.

Instead, MS wanted their own Java-like language with no strings attached. Java was a trademarked name, so they created a language with a different name but all the Java features (LANGUAGE features) that programmers liked so much, plus most of the features that Java programmers were begging for that Sun was sniffing at, plus the native extensions needed to write Windows apps that would only run on Windows AND would run so well they would, in general, be indistinguishable from native apps written in Visual C(++), and they built a great app builder (VC#) to go with it.

They did a beautiful job with Visual C# and rattled Sun so much that suddenly a lot of those "impossible" features we "didn't need anyway" became available in Java, but C# has always maintained a healthy lead over Java in nice features for client-side programming, IMO.

(And Java has maintained a superior overall adoption rate, especially on servers.)


> MS tried to produce a Java with native extensions:

Not exactly. MS replaced Java's existing native extension functionality (JNI) with Windows-only native hooks called JDirect. Interestingly, it did so with these @com (EDIT: sorry, I meant @dll -- @com was related to COM hooks, which stuck around well into the .NET era as attribute hooks) method macros that, in a way, prefigured attributes in both Java and C#.

EDIT: If by 'native extentions', you meant the WFC classes, then yes these were additions, not a replacement of JNI. But these were not part of the lawsuit per se. The suit focused on the removal of JNI and the corruption of the JVM spec with the JDirect functionality.

> plus most of the features that Java programmers were begging for that Sun was sniffing at

'most of the features' is pushing it a bit. The only feature that J++ had over Java 1.1 at the time was method pointers (delegate). The lawsuit focused on those corruptions of Java: removing JNI as well adding JDirect and the 'delegate' keyword. This, according to the court, violated the terms of the license agreement signed by MS.

Microsoft lost the lawsuit, and that was the reason they ditched J++ and began work on C#/.NET, which built upon many of the lessons learned in J++. I think otherwise MS's plan was to continue building an ecosystem around the MSVM not unlike what they eventually built around the CLR.

It would be interesting to compare the MS/Sun ruling with the recent Google/Oracle ruling, as the terms of the two suits were rather similar.

It would seem to me that the biggest difference there is that MS did in fact sign a license agreement with Sun that constrained the nature of their use of Java. Google did not sign any agreement, and I wonder if this was a calculated move on Google's part, in light of the MS/Sun J++ ruling.

Considering the recent ruling by Judge Alsup regarding Android's similar adoption/modification of the Java spec, does this mean Microsoft would have stood a better chance by simply implementing J++ with no agreement from Sun at all? On my naive, IANAL reading of it, that would seem to be the case.


>> plus most of the features that Java programmers were begging for that Sun was sniffing at...

>'most of the features' is pushing it a bit. The only feature that J++ had over Java 1.1 at the time...

The Java-like language with no strings attached with the different name and all the new features that I was talking about was C#, not Visual J++.

> Microsoft lost the lawsuit, and that was the reason they ditched J++...

But that's not the reason they created C#. They created C# because they wanted a Java-like language (Java-like as in having the Java advantages over C++, not as in Java-compatible) without any limits on how good they could make it for writing Windows client apps. When they created J++, they were still assuming that Java was a juggernaut that they would have to cooperate with to some extent or get left behind, like HTML. Over time, it became clear that Java was fizzling out on the client anyway, so the need to cooperate was fading fast while the desire to create something that would actually be great for Windows clients was becoming overwhelming. After Java failed as a client-side alternative for creating Windows apps, MS was going to fork their own language, regardless of its name.


I think the differences between C# 1 and the current Java have been rather downplayed by this discussion. C#1 was different from Java in a number of very important ways:

* You could call directly into the Win32 API (the issue that caused Sun and Microsoft to fall out)

* Value Types. Still being discussed for v8.

* Lambdas. Yes, in version 1.

* C# had enums, Java didn't. (Now Java has better enums than C#)

* A syntactic sugar for property get/set. This was extremely important to Microsoft.

* A decent COM-interop story. Again, very important to Microsoft.

Of course it was similar. It was a design goal to be able to run Java code on the .NET VM. But it was far from identical.

Jon Skeet could no doubt expand this list


I'm not so sure about lambdas in v1. I remember v2 added anonymous functions ( ex " delegate(int x){...}" ), and real lambdas not coming until v3.


You're correct, anonymous functions were 2.0, sorry. However, I'd argue that, syntax aside, they were already true lambdas. The expression stuff that V3 added isn't even on the Java roadmap.


Not relevant to the question, but:

Some of the comments in that thread illustrate a widespread misconception that C# isn't cross-platform. We're finishing up a game that runs on windows, osx, ios, and android, with a server on linux; and it's written in C#.

Microsoft's CLR and BCL implementation aren't cross-platform, but I haven't used those in quite some time.


While C# is cross-platform, almost everybody using it seems to be on Windows. Also, a bunch of the libraries people normally use with C# are Windows-specific (like WPF, I guess. Does anybody still use WPF?). Also, Microsoft has some patents which put projects like Mono in a potentially poor situation, which is why it isn't entirely embraced by the free software world.

Java, on the other hand, is, for better or worse, used heavily on all the different platforms. Moreover, most Java libraries (like Swing. Does anybody still use Swing?) are cross-platform.

I find F# a much more interesting language than C#. Do you know how F# behaves on Linux? While I've heard of people using C# on Linux and Android, I haven't heard anything about F#. Then again, the Linux people might just prefer OCaml.


I would, of course, agree that the majority of C# developers are on Windows (this seems natural). However, I think mono is in wider use than people think because of the fact that it's embedded in products like Unity. It's often not very obvious.

WPF was a definite non-starter for mono. Just too huge of an undertaking; much more focus on GTK#. Sometimes it's easier to bring something else to Windows than to bring Windows to everything else. In the case of WPF, it seems like not bothering was probably the correct move...

My understanding is that F# works just fine on linux and mac, but I haven't had the opportunity yet. Quite interested in this as well.


For standardized (and some other parts) of .NET/C#, Microsoft provided a patent license:

http://www.mono-project.com/Licensing#Patents


WPF is used extensively in enterprise. Alternatives are Windows Forms which is pretty old,and significantly less flexible, or web apps. WPF can host Windows Forms, so for legacy its a way better option then web.


I use WPF regularly. Initially it seemed quite alien compared to the windows forms world I was used to. Once I got to know how it works on the inside, I fell in love with it. In my opinion it is elegant and well thought through.


How do you package games to run?

Something that seems to be a disadvantage with Java over native builds is the way it complicates the task flow for users trying to install your software. Either they have to download a large distribution that includes the JVM inside it (are distributors even allowed to redistribute Java like this?) or else they have to download and install the JVM, and then configure their new application to point to it.

How does this work when you're using c#?


In the case of iOS, the code gets AOT-compiled and any unused bytecode is stripped out. Mono is statically linked in and adds about 6mb at the minimum.

On desktop, the necessary parts of the mono runtime would just be included with the distribution package; much like any other DLL. I don't think any developer in their right mind would ask people to download the mono installer. On the plus side, this doesn't pollute their system with registry entries or system files.

It's clearly not optimal to have that overhead, but it was preferential to porting to each platform in this case.


I assume you're using MonoTouch/Unity for your game?

How about your server code? Is that ASP.NET running on Linux? Or something else?


We've used both Unity and MonoTouch for different projects. They have their problems, but much less so, I think, than different native implementations on every platform.

On the server side, we just build the latest stable mono release and we made a socket server wrapped around libev (similar to what Manos de Mono does).

(I guess I lied, we have a small amount of web stuff in Ruby, but mostly just to serve content.)


From what I remember, it was one main thing: delegates

From Sun: http://java.sun.com/docs/white/delegates.html


Wow, they really thought that inner classes were an elegant and supreme solution. That strikes me as a really weird aesthetics attitude. Inner classes always felt like an accidental misfeature which everyone regretted about but couldn't remove it due to backwards compatibility.


Seeing how Java tries to play catch up currently, this reads down-right bizarre. :-)


They deleted it, but it can still be seen in Google's cache. Someone needs to tell Wikipedia and StackOverflow that they're going a bit overboard with all this deleting. Why don't they just demote stuff to show lower down in searches or something? http://webcache.googleusercontent.com/search?q=cache:mdxfQ2k...


Another very interesting question closed as off-topic.


Why interesting questions are getting closed all the time on Stackoverflow? It's not THAT off-topic and everyone are interested in it, what harm does it do that it needs to be closed...

Edit: Ok, now they deleted whole thing instead... because someone pointed out that it shouldn't been closed...


Mostly political reasons it seems. Java was always encumbered with patents and licensing restrictions especially for mobile usage, which came out the ugly way as we know with the latest Oracle's lawsuit. Even though Oracle didn't succeed, but nevertheless there was always a risk. I guess Microsoft didn't want to depend on that, but on the other hand wanted to leverage familiarity with Java to lure Java developers into using C#. Rather boring and uninspiring move (creating a close clone), but Sun can be partially blamed for not making Java truly free (like C++ for example).


Politics between SUN and MS was the main reason. But the low quality (and by that i mean things like doing value type allocations in the heap, shitty libraries for UI (Swing), the language not having common sense features such as delegates/properties etc) implementation of the JVM was another.


There are many reason's it made sense for MS to create their own Java-like system, but the "low quality" of the JVM implementations is not one of them. The JVM implementations (HotSpot, IBM J9) are more efficient than the CLR in virtually any sensible benchmark you care to run and it's been that way since about December 1998. e.g. http://shootout.alioth.debian.org/u64q/benchmark.php?test=al...


That shootout is between the JVM and Mono. The CLR outperforms Mono.

That being said, my understanding is that JVM programs slightly outperform CLR programs in terms of speed while CLR programs do better than those on the JVM(s) in terms of memory.



the benchmark is pretty much irrelevant, because if it was we would all be coding in C or Fortran, or why not machine code or assembly ? On the other hand I find that the mono project (young, open source implementation ), is doing quite great against java 7 (commercial implementation, unless I misread). It would be interesting to see how the openJDK is performing ? (the real question would be : is openJDK crippled compared to the Oracle - JDK ?)


>the benchmark is pretty much irrelevant, because if it was we would all be coding in C or Fortran

The point being debated is that the JVM is being developed and advanced more rapidly than the CLR. Performance is one way to demonstrate this. Performance does matter in many cases, and most folks aren't prepared to write their web services in Fortran.

>is doing quite great against java 7 (commercial implementation, unless I misread)

I would hardly classify 7x slower as "quite great"

>It would be interesting to see how the openJDK is performing ? (the real question would be : is openJDK crippled compared to the Oracle - JDK ?)

OpenJDK runs HotSpot, so no major difference


>>I would hardly classify 7x slower as "quite great"<< When half of that difference comes from running GC on a separate core, and we know that GC has not been tuned - perhaps we should call that particular difference accidental ;-)


Single core result Java still 3x faster than C#: http://shootout.alioth.debian.org/u64/benchmark.php?test=all...


Yes, and now look at the second half of my comment -- "and we know that GC has not been tuned" :-)

Start off with a different initial and maximum heap size (or a different GC option!) and the results may be different.


One factor is that Microsoft wanted a programming language with Java's language features that could be used to write Windows programs.

Sun was adamantly against the notion of people writing Windows programs in Java (or Unix programs in Java, or Mac programs in Java). Java programs were supposed to be for the Java platform.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: