tags:

views:

2113

answers:

6

Is anyone attempting to implement C# for the JVM? As a Java developer, I've been eyeing C# with envy, but am unwilling to give up the portability and maturity of the JVM, not to mention the diverse range of tools for it.

I know there are some important differences between the JVM and CLR but is there anything that is a showstopper?

+6  A: 

Look at Grasshopper. It is a Visual Studio-based SDK and patented .NET to Java converter that enables you to run .NET Web and server applications on Linux® and other Java-enabled platforms.

alex
Do you have practical experience with it? Also note the license is draconic for the free version.
Thorbjørn Ravn Andersen
+22  A: 

There are very significant differences between the CLR and the JVM.

A few examples:

  • Java doesn't have user-defined value types
  • Java generics is completely different to .NET generics
  • Many aspects of C# depend on elements of the framework - delegates etc. You'd need to port the library as well, even for language aspects.
  • Java doesn't support things like properties and events at a JVM level. You could fake some of this, but it wouldn't be the same.
  • I don't believe Java has any equivalent to pass-by-reference parameters, even at the JVM level
  • Subtleties to do with the different memory models would quite possibly bite, although I'm not sure how much is in the C# spec.
  • Unsafe code in general probably isn't possible in Java
  • Interoperability with native code is very different between JNI and P/Invoke. This probably isn't much of a problem for you.
  • You'd have to fake operator overloading and user-defined conversions

You could probably port a lot of C# - but you'd be left with a pretty unsatisfactory experience, IMO.

Going the other way, are you aware of IKVM? It allows you to run Java code in .NET.

Jon Skeet
+1, It's been awhile since I did hardcore Java but I also believe the JVM does not support deterministic finalization. At least it did not at one point. There would need tho be the concept of finalization / destructors in order to properly implement a good chunk of C# code.
JaredPar
Java has finalizers, and .NET finalization isn't deterministic either. There may be some subtle differences between the two, but I can't think of any offhand. I suspect Java's reachability tests are stronger than .NET's though: no finalization while another thread is still running an instance method
Jon Skeet
@Jared - it has try/finally, so it would be pretty easy to add using-statement to Java.
Daniel Earwicker
I think you could map value types onto reference types. Just make every assignment do a shallow clone!
Daniel Earwicker
@Earwicker: ... and change array allocation, and various other places where the semantics make a difference? I suspect it would be *very* hard to get it to work, *if* it's possible, and the result wouldn't be something you'd want to use.
Jon Skeet
@Earwicker I'm more concerned with passive finalization. Passive finalization is often used (correctly or incorrectly) for native resoucre cleanup.
JaredPar
@Jon, when were finalizers introduced? Last time i played with Java was 1.4 or 1.5ish. I'm going to feel stupid if they were around back then but I didn't remember them.
JaredPar
@JaredPar: They've been in since Java 1.0. You override the finalize() method.
Jon Skeet
@Jon, wow. I didn't ever do much playing around with native resources in Java so I'm not terribly surprised I missed that but shocked none-the-less. Learn something new everyday (hopefully)
JaredPar
Re: value types - I'm not so sure. The set of things that need mapping is quite limited, and the fact is that the performance difference with struct vs class is typically extremely small; no doubt it would hurt some applications but probably not most.
Daniel Earwicker
I think generics would be solvable too. You'd have to generate a java class with extra fields to hold the Class objects for the type parameters, so it would add some overhead, but then new T() and typeof(T) would be available.
Daniel Earwicker
The type information of a *class* is available at runtime. The issue with Java generics is that type information associated with *instances of that class* is lost. If you are suggesting that you would change the actual class of an instance, this would surely break existing code
oxbow_lakes
I understand it would be hard to map the CLR on the JVM. Would it be possible to emulate a CLR on the JVM instead, so that managed code could be run?
Thorbjørn Ravn Andersen
Well you can emulate either on either... but it would probably be pretty slow. Look at ikvm though, which I believe runs Java on the CLR.
Jon Skeet
@Jon Skeet: That gives you the worst of both worlds: Java's somewhat outdated language on Microsoft's proprietary platform.
Bart van Heukelom
+2  A: 

It might be simpler to write a converter from IL to bytecode. That way you'd automatically get support for any .NET language on the JVM.

However, this is such an obvious idea that if this hasn't already been done, it's probably extremely hard, or hard to do well/usefully.

Daniel Earwicker
You'd run into most of the problems I listed - different generics etc.
Jon Skeet
http://jsc.sourceforge.net/
mcintyre321
This is exactly what Grasshopper does (see @alex's answer above) it is indeed extremely hard to do well (I used to work on Grasshopper).
Motti
A: 

Why won't you simply use Groovy. It gives you probably everything you like in C# and miss in Java and it runs on JVM...

+3  A: 

Why not a language such as Scala? It includes many of the functional features you are likely envying from C#, but is already mature and on the JVM.

Matt Olenik
+3  A: 

Visit http://code.google.com/p/stab-language

The code below if a Stab language code for JVM

using java.lang;
using stab.query;
public class Test {
   public static void main(String[] args) {
   // Sorts the arguments starting with "-" by length and then using the default   
        // string comparison
        var query = from s in Query.asIterable(args)
                    where s.startsWith("-")
                    orderby s.length(), s
                    select s;
        foreach (var s in query) {
            System.out.println(s);
        }
    }
}
Vns
stab delivers much of the meat of C# language on JVM but does so in a way that is very Java inter-operable. So it's not strictly source code compatible to C# code written for the .NET CLR but it does enable a Java programmer to enjoy a very C# like language while getting the same quality byte code generated and having non-impedance interoperability with Java libraries and frameworks. It's the right approach to take for getting C# on the JVM.
RogerV