Why Java folks should stop looking down on C#: differences in similarities
blog.kalistick.com
blog.kalistick.com
In my experience it's always been the opposite: C# guys have always looked down on Java folks. And rightfully so: the language itself is nicer, the standard library is much nicer, and the CLR+CIL are vastly superior to JVM, especially in memory management department.
This is an extremely disingenuous statement. You may be referring to the fact that the CLR/C# supports the notion of structs, and allows native memory management. However, as someone who has experience working on both the JVM and the CLR, I can say that the CLR's GC is primitive compared to the JVMs.
Biggest advantage off the top of my head is the JVM's garbage collector has a lot more tunable options. Different application's various heap profiles necessitate using them in high performance applications. I don't believe the CLR allows you to specify the size or number of various generations, or the number of collecting threads, all possible with the JVM collector(s).
Either way, the G1 trounces both the CLR and JVM's current collectors, so the JVM for java 7 will make the advantage even more apparent.
I'm less familiar with the internal workings of JIT compilers. I don't believe the CLR supports static analysis type optimizations, but perhaps the CLR team focused their research in other areas. If anyone knows more details on the differences in their JIT strategies I'd love to hear more.
CLR processes are just processes. They're integrated into a native VM, they are capable of code sharing and they use more compact in-memory representations of built-in types. CLR was designed to run on machines we're running it on, not with a goal of selling more of "big iron". CRL is great for general purpose software development, without cowardly "long-running" or "on dedicated box" prefixes attached.
http://www.simple-talk.com/dotnet/.net-framework/the-dangers...
Of course, one might say "don't use such big heaps dummy!" But that's a workaround. Due to fragmentation, sub-second GC latency is still a tough problem even for 1-2 GB heaps.
If C# would lead the way in a GC-friendly memory management scheme (maybe regions or something similar) they might win a lot of Java converts.
I don't want this, seriously do not want. I don't want a language "with lovely features from C++". Explicit virtual, structs - please take those and leave me alone.
Lambdas are nice, some syntax sugar is nice, but not that creep.
Please don't take this as flamebait. I know a handful languages, I do backend development and I just absolutely don't need some language features and I fear that somebody would use them in their little library and would POISON the lifes of anybody who touches it.
Java has some "do not want" features too, like checked exceptions, but those are more or less solved these days.
Version 1, you import a third party library:
public class ThirdParty
{
public void calculateAndPrintResult()
{
System.out.println("1");
}
}
public class Mine extends ThirdParty
{
public void calculateAndPrintResult()
{
super.calculateAndPrintResult();
this.printResult();
}
protected void printResult()
{
System.out.println("2");
}
public static void main(String[] arguments)
{
Mine mine = new Mine();
mine.calculateAndPrintResult();
// Prints 1, 2
}
}
Version 2, third party has refactored and introduced printResult. You swap in the new third party library and suddenly the behavior has changed: public class ThirdParty
{
public void calculateAndPrintResult()
{
this.printResult();
}
protected void printResult()
{
System.out.println("1");
}
}
public class Mine extends ThirdParty
{
public void calculateAndPrintResult()
{
super.calculateAndPrintResult();
this.printResult();
}
protected void printResult()
{
System.out.println("2");
}
public static void main(String[] arguments)
{
Mine mine = new Mine();
mine.calculateAndPrintResult();
// Prints 2 ! (wrong)
}
}
While this example is trivial, bear in mind, when you have programming in the large, i.e. large codebases with a lot of third party libraries and many teams of developers, you would rather not have surprises like this pulled on you, or you pulling surprises like this on other people.It can take a lot of work tracking down this kind of bug.
When you finally realize this type of issue arises despite everyone following "best practice" OOP, then the reason is because "best practice" OOP is not actually best practice.
I can see how that would become a problem, a potentially terrible problem, but for a situation like that, wouldn't private methods solve that problem?
I can see more complex situations with this, but at some point, and they'd be annoying to break down. I don't throw out my position on this, though, as good documentation could help at least a few cases of this. Also, newer versions of Netbeans encourage the use of the @Override attribute, to help ensure things like this down happen, I imagine (I don't actually know what the @Override attribute is for, as I've only used it in large Java projects where I was the only developer).
edit: unless you misspell the method you intend to override and forget to include the annotation, in which case the compiler can't help you :-)
Not if the third party developer intends to override it in his own subclasses.
Documentation may solve the issue, but this goes against the "just works" philosophy.
The root of the problem is versioning. Your class was developed against version 1 of the base class. You expect further changes in implementation of the base class should not materially affect your running code.
To achieve this, one of the sacrifices is the all methods are not overridable by default (i.e. not virtual), but instead have to be explicitly declared virtual AND the subclass has to explicitly state they wish to override the base class.
It is namespace pollution of a very subtle and devious kind.
Implementation inheritance breaks encapsulation. It creates an intimate entanglement between the internal implementation details of the super- and sub-classes. Every time you extend a class or override a method that wasn't explicitly and carefully designed to be subclassed and overridden safely, you are _writing hacky code_.
There are, of course, places for hacky code. If you understand why something is hacky and feel it's a worthwhile trade-off then by all means you should be able to do it. Java, though, encourages people to pepper their code with such hacks before they have learned why they shouldn't.
I thought Java had this same issue, but if methods aren't explicitly virtual you're effectively always in this state. So clearly Java must deal with construction/virtuals differently.
I think Microsoft has managed the language really well, even taking painful decisions like backward-incompatible versions to properly support generics. Kudos to the team !
There is so much that might seem like syntactic sugar at first, but when you get into it, you can just express yourself in a lot less code compared to Java. Sadly, there also seems to be a culture thing around Java to make things needlessly complicated, whereas the culture for C# is about writing less.
In practice a lot of developers end up using open source build tools like nant and rake in preference to msbuild as they tend to be more flexible in other build environments like TeamCity/Hudson.
1) it does not have to worry about language standardization and the various community processes that accompany Java.
2) Anders is exceptionally good at deciding what language features are go/no go.
That said, the standard is very much owned and written by Microsoft. You're absolutely right that they don't have to work through a JCP-like process.
Microsoft has pushed Silverlight as a .NET vm that runs on Mac, with a smaller framework library. So far, this has met will little traction. I don't think it will encourage MS to push this further and wider.
* Lack of first class functions
* 'null' type
C# has fixed both of those.
Scala can evolve at a much faster pace than Java as well, given that the core language is tiny and most of the language constructs are implemented as libraries.
We weren't certain that C# needed it. Until we tried it.
return purchaseList.OrderBy(pur => pur.Date).FirstOrDefault();
and carry on. It's great. You don't tend to have that fine granularity when working across languages.I don't know if you missed F# or not, but if you want a fully functional language in the ML / Ocaml lineage on .Net, you can write some code in that and interoperate.
Value types (so you can have complex data types that are never null)
Nullable value types (T? or Nullable<T>)
Null coalescing operator
Using those three features appropriately makes it a lot easier to avoid unexpected nulls causing bugs in your software.
http://stackoverflow.com/questions/178026/why-is-null-presen...
For example, in the type system we do not have separation between value and reference types and nullability of types. This may sound a little wonky or a little technical, but in C# reference types can be null, such as strings, but value types cannot be null. It sure would be nice to have had non-nullable reference types, so you could declare that ‘this string can never be null, and I want you compiler to check that I can never hit a null pointer here’.
50% of the bugs that people run into today, coding with C# in our platform, and the same is true of Java for that matter, are probably null reference exceptions. If we had had a stronger type system that would allow you to say that ‘this parameter may never be null, and you compiler please check that at every call, by doing static analysis of the code’. Then we could have stamped out classes of bugs.
Instead of being able to send null DateTime, the WS dictates that the client must send something. Therefore, the client sends Epoch date thus the code must handle this properly.
What about dealing with Database when NULL actually means something (in certain situation, we do want to put NULL instead of some random value/junk).
There's always trade-off.
E.g. I frequently need to check if params are null and then throw an exception at run time. If I could declare a param as requiring a value then the error could usually be caught at compile time.
But my point is "how, do you think, people use it in the real world".
It's just like any other programming languages: people tend to abuse it.
At the end of the day, it all depends on your developers.
Sort of. In your WS example, if you had better developers then they could have defined the interface to accept Nullable<DateTime> instead of DateTime. So the language does let you express that null is an allowed value.
The feature request for the language is to make it possible to express Nonnullable<MyClass>. Regardless of your developers, the best that they would be able to do is throw an ArgumentNullException (which I see thrown for all over the place) without that support.
I'll accept that there may be a situation where a client sends junk to a service, and the service treats the junk as null, but that requires both sides to be in on it - in which case, they would be able to agree to a signature change instead. But they can only agree to the signature change if the language supports it.
I favor switching the language/environment once you feel that you need more expressing power. E.g. use Scala, Jython or Clojure if you need JVM, or perhaps Erlang for server-side.
Checked exceptions are not something that I'd happily give up. We do have unchecked exceptions (RuntimeException), and the JRE generally uses them where appropriate. But what about methods like Inflater.inflate, ImageIO.read, or Class.getMethod? If these didn't throw checked exceptions, we would sometimes forget to catch exceptions which should almost always should be caught. It would be a step in the direction of a weaker type system, unhelpful errors, and less graceful recovery.
Regarding initializers, we can do the same thing in Java by giving an initializer block to an anonymous class:
List<Integer> L = new ArrayList<Integer>() {{
for (int i = 0; i < 10; ++i)
add(i);
}}; var l = new List<int>(Enumerable.Range(0, 10));Also the event / delegate thing makes C# really nice for GUI stuff.
You are right C# is nice for GUI stuff, but... but again only for Windows, not even for mobile, because as for now WinMo is far behind iOS and Android... and you may use Java on Android, and BlackBerry ;-)
All those other things that people have already commented on like Lambdas, expression trees, events and delegates, are incredibly nice to have.
Here's the first thing I write when I start a Java project, followed directly by an abstract class based on it:
public interface ICallback<T> { public void Invoke(T state); }