Two new C# 3.0 features that Java needs

C# 3.0 is out. You can get the specification, a compiler other goodies from here.

I am programming in Java almost exclusively for the last two years. In this post I will discuss two new features of C# 3.0 that I’d like to see in the next versions of Java.

Below there is a code fragment from the XLinq in action video that demonstrates my two new favorite features (local variable type inference and lambda expressions):

var contacts = doc.Descendants("contact")
      .Where( a => (string)a.Attribute("category") == "home")

The above code fragment will query an XML document (the XDocument object that is assigned to the doc variable) to retrieve all contact elements with the category attribute matching "home".

In the above code we didn’t specify the type of the contacts variable in the variable declaration. Instead we used the new C# 3.0 keyword var. When we use the keyword var in a variable declaration the type of the variable is inferred by the compiler for us and we do not have to specify it. This is called local variable type inference. The type is inferred at compile-time after checking the type of the expression on the right of the assignment.

Please note that the variable contacts has a type and its type remains the same (statically typed). You cannot reassign something that has a different type from the above expression to the contacts variable. This is in contrast with dynamically typed languages like Python and Ruby where you also do not declare the type of variables but the type of the variables is determined at run-time and the type of a variable can change dynamically (you can assign a string to a variable and then assign an integer to the same variable).

Three people have asked for this feature with a RFE to the SUN’s Java bug database. All of the RFEs are in “Closed, will not be fixed” state because people at SUN believe that types in variable declarations provide readability and valuable redundancy.

Below I have included information about the RFEs.

Bug ID: 4879776
Synopsis: Constructor type inference (JSR14 + JSR65 ++)
Submit Date: 17-JUN-2003

Bug ID: 4459053
Synopsis: Type inference for variable declarations
Submit Date: 15-MAY-2001

Bug ID: 6242254
Synopsis: Language support for type inference
Submit Date: 17-MAR-2005

I agree that repetition is good and many times helps readability but now that Java 5 has generics the variable declarations can be very long and noisy.

Consider the below code fragments:

// 1. Non generics with construction
Pair p = new Pair(1, 2);

// 2. Generics with construction
Pair<Integer , Integer> p = new Pair<Integer , Integer>(1, 2);

// 3. Generics with type inference and construction
var p = new Pair<Integer , Integer>(1, 2);

// 4. Generics with method invocation
Pair<Integer , Integer> p = o.getPair();

// 5. Type inference with method invocation
var p = o.getPair();

Compare (1) with (2). (2) is very long compared to the non-generic version and the repetition is annoying. I believe that type inference in (3) is very clean and easy to read. Now add to this that most Java types have really long names. Breaking simple variable declarations to multiple lines isn’t very easy to read.

Now let us consider (4) and (5). In (4) we do not have repetition of the type information and the declaration is easy to read and understand. In (5) we have type inference and the programmer does not immediately see the type of the variable p. I agree that since the programs are read more times than they are written and if the programmer does not use a modern IDE (like Eclipse, Netbeans or IDEA) this makes the program harder to understand. But if the language supports type inference a programmer is free to use (4) instead of (5) and (3) instead of (2) to get the best of both worlds.

I will also like to add that code like this

HashMap<Integer , LinkedList<Integer>> map = 
  new HashMap<Integer , LinkedList<Integer>>();

is acceptable only because we use sophisticated IDEs with code complete (we have to write HashMap<Integer, LinkedList<Integer>> twice). Why the same argument cannot be used to accept the code in example (5)?

My conclusion is that we do not lose in type safety and we improve productivity and code readability with just a minor syntactic change. I wonder why statically typed languages like Java and C# did adopt type inference earlier or from the start like functional languages as SML and Haskell.

The other feature that I like is lambda expressions. Lambda expressions (or if you prefer closures) are the basic building block of functional programming. Lambda expressions can be found in functional programming languages like LISP, Haskell and SML and also in modern scripting languages like PERL, Python, Ruby and Groovy.

Now I might be a little biased because I learned to program in Scheme and SML but I do believe that functional programming provides very elegant solutions to a lot of problems. IMHO the existence of lambda expressions in languages like Ruby and Groovy is one of the reasons why so many Java developers are using them.

Consider the below code where I have implemented the equivalent code with the XLinq example in Java with dom4j. (Dom4j is a great and fast DOM API for XML processing in Java)

Document doc = ...
Document contacts = new Document();
for ( Iterator i = doc.elementIterator("contact"); i.hasNext(); ) {
  Element contact = (Element) i.next();
  if ("home".equals(contact.getAttribute().getValue()))
    contacts.add(contact);
}

In my humble opinion the C# version is not only more short but more clean and elegant. Martin Fowler recently wrote a post on his blog about how closures (lambda expressions) and collections fit nicely together. I suggest that you read it since it provides a lot of examples (in Ruby) where the functional way of doing things is simpler and more elegant.

There are two RFEs at the SUN’s Java bug database about adding lambda expressions to the Java programming language. Both of the RFE’s are in “In progress, request for enhancement” state so we can vote to bring this feature to Java.

Also Graham Hamilton, Mark Reinhold and Gilad Bracha in their “Evolving the Java Language” talk this year at JavaOne said that they are considering to add closures/method references (lambda expressions) to the next version of Java. (Please note that I wasn’t at JavaOne and I have only seen this in their slides. I am eagerly waiting for the multimedia content of the presentations to become available online).

If you are a Java programmer who things that lambda expressions (closures) could be useful in the Java programming language take five minutes of your time and vote for both of the below RFEs.

Bug ID: 5014235
Synopsis: Closures support instead of annonymous inner classes
Votes: 13
Submit Date: 16-MAR-2004

Bug ID: 4483171
Synopsis: Adding support for delegates and method references
Votes: 8
Submit Date: 23-JUL-2001

BTW Ted Neward has written a very good overview of all the new C# 3.0 features.