Sunday, 14 December 2008

Devoxx 2008 - Whiteboard votes

Devoxx 2008 is over :-( But is was a great conference again. And Java really started to feel alive again with real discussions of JDK 7.

In this post I'll go through the general discussions that were held on the Devoxx whiteboards. The figures given are of course indicative only. They are based on those Devoxx attendees who actually participated on the whiteboards. Also, the figures are a record taken at the end of Thursday (Friday scores not included).

The whiteboard photos are also available which provide additional information. Bear in mind that my figures may disagree with the photos in some small way based on when I counted the results relative to when the photos were taken.

Are you considering using JavaFX ?

Java FX had its big conference launch at Devoxx. This question captured developers feelings about it:
   

Yes62
Maybe78
Next version21
Never45
What is jfx?6

It seems clear that Devoxx attendees were pleasantly surprised by Java FX, and are thinking about using it.

What Testing Framework/Tools are you using ?

Testing is an essential developer activity, but what tools get used? I've broken out the big 3 unit testing tools here.
   

JUnit354
JUnit4102
TestNG23
Selenium32
None3
Testing?!5
EasyMock17
JMock2
HTMLUnit2
Fitnesse3
SOAPUI11
Cobertura5

Obviously, a wide range of tools are in use, but in the unit test area JUnit still rules the roost.

REST vs SOAP

A hot topic with many developers who still have to try and convince sceptical managers that REST is a valid solution. I'm displaying the main numbers for the question here:
   

REST50
SOAP17
Both30
JSON6

So, developers prefer REST to SOAP. Somehow I'm not surprised!

What IDE/Editor do you use ?

A question that will always bring out strong opinions:
   

Eclipse214
Netbeans64
IntelliJ126
Vi/vim9
Textmate6
Jdeveloper5
Notepad++7

I'd have expected a stronger showing for Eclipse than this. Maybe Eclipse users have less strong opinions about their tool as Netbeans and IntelliJ users?

Which Java VM are you using ?

How up to date are the versions of Java we use? The question asked Devoxx attendees to mark all they are using:
   

0.9b2
1.03
1.1b6
1.36
1.474
1.5216
1.6255
1.72
1.7 (patched)4
1.7 (closures)2
Java ME13

So, more people are using Java 1.6 than Java 1.5. Interesting.

Checked exceptions ?

Checked exceptions are a feature essentially unique to Java. Many, like me, think they were a very bad idea. But what about Devoxx attendees:
   

Good idea34
Bad idea36
Both, It depends6

Opinion seems split on this topic. Although I should note that the number of votes was lower on this issue, so maybe there is an element of "don't care".

What is your favourite JVM lang other than java ?

The JVM isn't only about Java now. What else are people using:
   

Groovy49
Scala30
JRuby14
Jython10
Fan5
PHP4
Clojure5
Don't care17

So, Groovy is looking pretty popular right now, with Scala seeing some good use. There is interest in additional languages too and this is healthy for the JVM's future (and personally, I was pleased to see Fan get 5 votes at this early stage in its life).

Summary

Thanks again to all the Devoxx voters. I'll write up about language change issues soon. Feel free to comment on any of the vote results.

Tuesday, 9 December 2008

Java 7 - small language changes

Todays news that there are likely to be language changes in JDK 7 was a bit of a surprise. It seemed like the chance had passed.

Small language changed for JDK 7

Joe's post isn't very long, but it is clear.

  • "I'll be leading up Sun's efforts" - so its supported by Sun
  • "develop a set of ... language changes - so its more than one change
  • "small language changes" - small means no closures or properties
  • "we'll first be running a call for proposals" - community involvment
  • "in JDK 7" - in the next version (but why does the blog not say Java 7?)

I've used this blog, and previous visits to JavaPolis (now Devoxx) to discuss possible language changes. Some have been good ideas, others not so good. The main point was to provide a place for discussion.

The next phase after that was to implement some of the language changes. This has been achieved with the Kijaro project. As far as I'm concerned, anyone can write up an idea for a Java language change, and then I'll provide commit access at Kijaro for it to be implemented in javac - no questions asked.

Expectations

So, before we all submit lots of crazy ideas and get carried away, lets remember that Sun provided some hints at JavaOne 2008. This presentation includes the following as ruled out:

  • Operator overloading (user defined)
  • Dynamic typing
  • Macros
  • Multiple dispatch / multi-methods

And the following as 'under consideration':

  • Multi-catch in exceptions
  • Rethrowing exceptions

The following are listed as 'long term areas of interest':

  • Parallel algorithms
  • Versioning of interfaces
  • Delegation
  • Extension methods
  • Structural typing
  • Pluggable literal syntaxes

So, there is already quite a wide list on the table. Plus, there were other ideas suggested at last years JavaPolis, by both Josh and Neal:

  • Variable declaration type inference (for generics)
  • Enum comparisons
  • Switch statement for strings
  • Chained invocations, even when method returns void

In addition to all the above, I strongly suspect that there isn't going to be a chance to tackle problems with generics. This is similar to closures and properties. There isn't the timesclae or manpower to tackle these big issues in the timeframe being talked about (especially now Neal Gafter works for Microsoft).

My ideas

Well, I'll mostly save those for another day. But I would like to see a proper consideration of enhancements to help with null handling. And enhancments to the for-each loop.

Saying NO!

Finally, an appeal to Sun. Many in the community are deeply sceptical of any language changes at this point. The message should be simple - people need to feel that there is a clear means to vote or argue AGAINST a proposal, just as much as to make suggestions FOR change. Although I don't expect to make much use of the facility, I know there are many that do want to express this opinion.

Summary

This is a new departure for Sun in so openly asking for ideas from the community. We need to respond and reply with thoughtful ideas for what will and will not work.

Sunday, 9 November 2008

Java language change - Unique identifier strings

This last week I've been refactoring some old code in my day job to simplify some very crusty code. One of the parts of the refactor has made me write up why language features often affect more than is immediately obvious.

The case of the Unique Identifier String

The specific code I've been working on isn't that significant - its a set of pools that manage resources. The important feature for this discussion is that there are several pool instances each of which has a unique identifier.

When the code started out many years ago, the identifier was simple - the unique name of the pool. As a result, the unique identifier was the pool name, and that was defined as a String:

// example code - hugely simplified from the real thing...
public class PoolManager {
  public static Pool getPool(String poolName) { ... }
  ...
}
public class Pool {
  private String poolName;
  ...
}

Internally, the manager consists of maybe 25 classes (its over-complex, no IoC, and needs refactoring, remember...). Most of the 25 classes have some kind of reference to the pool name, whether to access configuration, logging or some other reason.

At some point in the past, a new development was commissioned that affected the whole system. The new development - maintenance code - was to allow multiple sets of configuration throughout the system.

To achieve this, everywhere that accessed configuration needed a unique key for the configuration it needed to access. Again, as this was a simple lookup, a String was used. And, since the pooling component was affected, a second unique key was added:

// example code - still hugely simplified from the real thing...
public class PoolManager {
  public static Pool getPool(String poolName, String configName) { ... }
  ...
}
public class Pool {
  private String poolName;
  private String configName;
  ...
}

Now, in order to complete the change, the config name was rolled out to most of the 25 classes alongside the poolId. In effect, the true 'unique id' for the pool became the combination of the two separate keys of poolName and configName.

Now, we could debate lots about this design, but thats not the point. The point, in case you missed it, is that we now have up to 25 classes with two 'unique ids' that are really one. In addition, this creates confusion in what things mean. After all, with two keys we now need a map within a map to lookup the actual pool, right? (again, I know the alternatives - this is a blog about what maintenance code does over time, and how to tackle it...)

OK, so how might we improve this using Java?

A better design

If the original developer had coded a PoolId class then the overall design would have been a lot better:

// pre-maintenance:
public class PoolId {
  private String poolName;
  ...
}
public class PoolManager {
  public static Pool getPool(PoolId poolId) { ... }
  ...
}
public class Pool {
  private PoolId poolId;
  ...
}

Now, the maintenance coder would have had a much easier task:

// post-maintenance:
public class PoolId {
  private final String poolName;
  private final String configName;   // NEW CODE ADDED
  ...
}
// NOTHING ELSE CHANGES! PoolManager and Pool stay the same!

Wow! Thats a lot clearer. We've properly encapsulated the concept of the unique pool identifier. This allowed us to change the definition to add the configName during the later maintenance. This isn't rocket science of course, and there isn't anything new in this blog so far...

Now, what I want to do is ask the awkward question - Why wasn't the PoolId class written originally?

Its vital that we understand that question. Its the root cause as to why the code now needs refactoring, and why it is hard to understand and change. (And bear in mind this is just an example scenario - You should be able to think of many similar examples in your own code)

Well, lets look at the PoolId class in more detail. In particular, lets look at the code I omitted above with some '...'.

// real version of PoolId in Java - pretty boring...
public final class PoolId {
  private final String poolName;
  
  public PoolId(String poolName) {
    if (poolName == null) {
      throw new IllegalArgumentException();
    }
    this.poolName = poolName;
  }
  public String getPoolName() {
    return poolName;
  }
  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }
    if (obj instanceof PoolId == false) {
      return false;
    }
    PoolId other = (PoolId) obj;
    return poolName.equals(other.poolName);
  }
  public int hashCode() {
    return poolName.hashCode();
  }
  public String toString() {
    return poolName;
  }
}

Now we know why the original developer didn't write the class PoolId. Very, very few of us would - the effort required is simply too great. Its verbose, boring, and probably has enough potential for bugs that it might need its own test.

But the way we write this class - what it actually looks like - is a language design issue!

Quick composites

It is perfectly possible to design a language that makes such classes really easy to write. For example, here is a psuedo-syntax of an imaginary language a bit like Java:

// made up language, based on Java
public class PoolId {
  property state public final String! poolName;
}

The 'property' keyword adds the get/set methods (no need for set in this case, as the field is final). The 'state' keyword indicates that this is part of the main state of the class. Adding the keyword generates the constructor, equals(), hashCode() and toString() methods. And finally, the '!' character means that the string cannot be null.

Adding another item of state is really simple:

public class PoolId {
  property state public final String! poolName;
  property state public final String! configName;
}

Suddenly, adding a new class for things like PoolId doesn't seem a hardship. In fact, we've changed implementing the right design to doing the easy thing. Basically, its about as easy as its ever going to get.

My real point is that if Java had a language feature like this, then there would a much greater chance for the better design to be written. After all, most developers will always take the lazy option - and in Java that is way too many String identifiers.

So, does this imaginary language exist? Well, some get a lot closer than Java, but I don't think any language achieves quite this kind of brevity (prove me wrong!).

In addition, I'm arguing for Fan to encompass 'quick composites' like this. After all, I'd argue that most (80%?) of the classes we write could have auto-generated equals() and hashCode() based on a 'state' keyword.

Summary

As a community of Java developers, we need sometimes to realise that the language we develop in can actually hold us back. A language design feature like this is not just about saving a few keystrokes. It can fundamentally change the way lots of code gets developed simply by changing the better design from very hard/verbose to really easy. And the knock-on effects in maintenance could be huge.

Finally, I want to be clear though that I am NOT advocating a change like this in Java. Java is probably too mature now to handle big changes like this. But new languages should definitely be thinking about it.

Opinions

What languages come close to this design?
What percentage of classes in your codebase could have their equals()/hashCode() methods generated by a 'state' keyword?
Opinions welcome!

Thursday, 23 October 2008

Life in the Fan lane - less NPEs

Since I last blogged I've been contributing to the development of the Fan Fantom language through lots of discussions. One of the latest features to be added is targeting a major reduction in NPEs.

Fantom and NPEs

The Fantom programming language is a relatively new language for the JVM (it compiles to bytecodes). However, it also compiles to .NET CLR making it very portable, with its own set of APIs.

Its a language that is easy for Java and C# developers to grasp (familiar syntax and concepts). It also fixes up many of the weak points identified in Java, with closures properly designed in, understandable generics, much less boilerplate and clever concurrency. Further, it performs close to, or as well as Java, because it is a statically typed language.

// find files less than one day old
files = dir.list.findAll |File f->Bool| {
  return DateTime.now - f.modified < 1day
}
// print the filenames to stdout
files.each |File f| {
  echo("$f.modified.toLocale:  $f.name")
}

When I first came across the language, I immediately saw its potential as a Java successor. It is an evolutionary language. Simple for Java developers to move to, yet with clear potential productivity gains. One thing irked me though, and that was the handling of nulls, because Fantom had a model exactly like Java, where any variable could be null.

This has changed recently however, and now Fantom supports both nullable and not-null types:

 Str surname      // a variable or field that cannot hold null
 Str? middleName  // a variable or field that can hold null

At a stroke, this allows much more control within your application of the presence of null. No longer do we have to write in JavaDoc (or lengthy nasty annotations) as to the null status of a variable.

For example, you cannot compare surname to null, as that makes no sense. In the Java defensive coding style, it is often the case that variables are needlessly checked for null. This additional code gets in the way of the real business logic, and requires extra tests and analysis. With Fantom's null/not-null choice, a not-null variable can simply be relied on to be not-null, and any attempt to compare a not-null variable to null is a compile error.

Further to this, the type system allows you to block the presence of null in lists and maps. This is often an area forgotten when passing collections to methods - until the NPE strikes.

 Str[] list     // a list that cannot hold null
 Str:Int map    // a map that holds non-null strings to non-null integers
 Str:Int? map2  // a map that holds non-null strings to nullable integers

Finally, the null-safe operators (?., ?-> and ?:) are all prevented on operating on not-null variables. The ?. operator is a null-safe method invoke, that returns null if the LHS is null, so clearly this makes no sense if the LHS is a not-null variable.

One point to note is that not-null is the default. Why is that?

Well, it turns out that is the most common state for variable. Most programmers intend most variables to not hold null. In converting the Fantom sourcebase figures of 80% were not uncommon (ie. 80% of variables were originally intended to never hold null). Clearly it makes sense to make the most common case the default, and thus to make handling null a special case.

And what does the nullable/not-null variable actually represent? Well, most variables are objects, so once it gets to bytecode there is no difference. But for Int and Float, the non-null types can be converted to the primitive bytecodes for Java's long and double. This means that Fantom now has access to primitive level performance at the bytecode level which is going to allow Fantom applications to speed along nicely.

Summary

Fantom is coming along nicely. NPEs are a major headache in todays systems, and Fantom's approach will eliminate many of those errors. Further, it will eliminate much of the defensive code that is added to protect against values that will never actually be null - leaving Fantom even more decluttered.

Opinions welcome on NPE handling - something that seems to have been a complete lack of priority in Java.

Friday, 20 June 2008

Friday fun - Or is this a serious AJAX comment?

This is a genuine street sign from Nelson, New Zealand. But perhaps its telling us that AJAX really is a dead end and we need something better?! Or that now we've started using AJAX there's no escape?!!

(Well I found it funny anyway ;-)

Tuesday, 17 June 2008

Firefox download day farce - never ignore time zones!

So, the big download Firefox world record attempt has started in a farce. Why? Because of a complete lack of understanding of and planning for date and time issues!

The 'download day' has been advertised as 17th June 2008. But there is no clear information as to when on the 17th June. So when would you assume?

Personally, I would naturally assume the 24 hours starting at midnight UTC. But no. The 24 hour period actually starts at 10am Pacific Daylight Time. Crazy!!!

The recriminations on this have already started. The main complaints include bad planning, American focus and plain stupidity. It already looks like quite a few people assume that the release has been delayed. Some appear to have given up on the download.

Again with dates and times the message is clear - time zones are a pain, but you can't ignore them!

Thursday, 12 June 2008

The Fantom language - Is it JavaNG?

For many moons there have been discussions about what we need to do to 'fix' Java. But what might the language look like if we applied all the possible fixes?

The Fantom programming language

Many (all?) of the ideas for creating a 'better Java' are not new, and have been talked about many times over the years. Ola Bini produced one list, which included no primitives, enhanced generics (no angle brackets), closures, method references, implementation in interfaces, some type inference, no checked exceptions and non-null variables. This is a good list and mirrors many of the discussions that have been held on this blog.

Of course, this JavaNG/Java3/BetterJava language doesn't exist does it?

Well, perhaps it does.

The Fan Fantom programming language is one I've been watching for a couple of months since it first launched its website. Its statically typed like Java and Scala, although there are some dynamic features.

I've been meaning to blog about it for some time, but Cedric beat me to it (and its a good writeup too).

Basically, Fantom fixes 95% of the pain points in Java in a manner and style that is close to that which you'd naturally pick if you were creating JavaNG/Java3/BetterJava. Here is a quick rundown of the key features and changes:

Pods, Types and Slots

The basic unit of grouping code is the Pod. This is like a combination of a Java package and module. It forms a key part of the name of any type in the same way as the package name does. But because it is also the module, it is easy to find missing classes - its like every class file knowing what jar file it is stored in. There is also a module level access specifier ('internal'), which is a cross between package scope and proposed 'module' scope in Java.

The two main types of type are classes and mixins. Classes are as expected, with single inheritance. Mixins are like interfaces, but can have implementation too, providing convenient and safe multiple inheritance if required.

Slots are the contents of classes and mixins. There are only two types of slot - fields and methods. All fields behave as properties, and are accessed via methods. You don't need to manually write the getter/setter, but you can if you need to, such as with calculated fields. Methods are pretty much as expected, except that you have to declare them as virtual in order to allow them to be overridden (and you have to declare override if you are overriding).

One key point is that all slots have unique names. This means that a field cannot have the same name as a method. This is a Good Thing, and allows method/field references to just reference the slot name (contrast this with the FCM method reference spec).

It also means that methods cannot be overloaded! But this is also a Good Thing, when combined with default values for method parameters, for example either of the last two arguments may be omitted and will default to zero:

Date withDate(Int hour, Int minute, Int second := 0, Int milli := 0) {
  ....
}

The totality is a very simple, but consistent, basic structure.

Constructors

Constructors are defined like static methods, but use the method name 'make' by convention. This method name and design is designed to allow easy switching from creation of objects to returning cached objects (or specialised subclasses) without affecting the caller:

class Date {
  new make(Int hour, Int minute, Int second := 0, Int milli := 0) {
    ....
  }
}

The 'new' keyword indicates that the method is a constructor.

Assignments and operators

All assignments use the := symbol. This clearly separates them from any other usages of =. It also enables a basic form of type inference when declaring local variables:

  value := 6
  str := "Hello world"

Note that there was no need to declare the variable type (Str/Int). Declarations of fields still require the type to be specified though.

Fantom also supports operator overloading by delegation to methods. Thus, writing a method with a special name will cause the matching operator to be allowed.

As a result, there is no need to call a.equals(b). The == operator is mapped to the equals method - this one change makes code a lot neater.

Immutability and Threading

Immutability (using the 'const' keyword, although a different meaning to C) is built into the language. Fields and classes can be immutable, as these gain extra power in the language.

The main benefit is with multi-threading. The language prevents there being any shared mutable state between two threads. Only immmutable objects may be freely passed between threads. If you need to pass a mutable object to another thread, then it must be serializable (using the built in serialization) and it will be sent to the new thread as a serialized message There is thus no synchronized keyword.

Collections and Closures

Collections and Closures are the only places where anything like generics appears. The collection classes have dedicated type signatures, which look like Java array signatures:

 String[] listOfStrings := ["one", "two", "three"]
 String:Int[] mapOfStringsToInts := ["one": 1, "two": 2, "three" : 3]

Note that both the list and map also have a literal syntax to define initial contents.

Closures are built in, and the API is written to work with them. The syntax is modelled after Ruby, but is pretty readable to a Java developer, using pipes to define the closure arguments:

 list := ["one", "two", "three"]
 list.each |Str val, Int index| {
  echo("$index = $val")
 }

Note how local variables can be accessed and output from within a string (like Groovy amongst others).

Dynamic coding

Fantom encourages more dynamic coding styles. If you use the dot to call a method (as per normal Java) then the method is compile time checked. If you use the arrow operator, then the method is called by reflection. Further, if the method called by reflection doesn't exist, then this error can be caught (the 'trap' method) which is like the 'method missing' concepts in other languages and enables powerful DSLs to be written.

  obj.doStuff()   // compile-time checked call, as per Java
  obj->doStuff()   // runtime reflection call

This can also be thought of as enabling duck typing.

API

Fantom has its own API. It does not directly expose the Java API, although you can access it via the 'native' keyword. The benefit if this is the removal of all the bad and broken parts of the Java API.

The Fantom authors philosophy is to provide all the useful features of the Java API, but in less classes. Thus, the IO API consists of just 4 key classes, with byte/char operations on the same class, and buffering assumed.

Odds and ends

Lines do not need a semicolon at the end. A newline will suffice.

There is built in serialization to a JSON like syntax. This is actually a subset of the language, and can be used to initialise objects at creation time in normal code.

Methods may have convariant returns like Java. But they can also have Self type returns.

Methods can be declared to run 'once', and then cache their value.

If, while, and basic for loops are the same as in Java. Switch statements are better, as they can't fall-through.

Exception handling is as per Java, with try, catch and finally. All exceptions are unchecked (yay!)

The default type for numbers with a decimal point is a BigDecimal equivalent, not a double equivalent. This will mean a lot fewer numerical errors.

Fantom runs on the JVM and the .NET runtime. It manages this by writing to a temporary intermediate format, which then gets further compiled to the right bytecode.

The website is really good and detailed.

Comparing to Java

Fantom is not Java, it is its own language. Yet, it is many, many ways the natural result of applying all the changes that the blogosphere asks for in Java. Just for that reason it pays to evaluate it closely.

Is Fantom a good language? The answer is a qualified yes. At the moment, it looks like a very well designed language I have very few points of contention with it - the main one being there is no non-null support. Minor points include some choices for coding standards (open curly brace positioning, and when to use method parameters).

Is Fantom a new language? Not really. It is a consolodation language, which is what James Gosling claims Java was (ie. a language that doesn't invent much that is radically new. Most of the ideas have been seen elsewhere, but Fantom has a particular JavaNG feel about it.

What are my key features? Built in modules, immutability and safe threading, closures, and a really great solution to generics (ie. only support them on Lists, Maps and Closures). The local type inference, no semicolons, == for equals and interpolated string are four minor features that make a big difference too.

Summary

Fantom is worth checking out. Whether it suceeds as a language is up to many factors - it needs an IDE for example, and a lot of luck.

The key point for me is that Fantom represents much of what JavaNG/Java3/BetterJava would look like if all our ideas were adopted. And while it has many similarities to Java, there is also quite a sense of difference. Perhaps, the biggest aspect of this is that the APIs are different. But that is perhaps inevitable if you want to get any real benefit from closures and fixing generics (by simplifying them).

And that perhaps gives us the definition of where JavaNG/Java3/BetterJava ends and BeyondJava starts. If the language is based around the Java APIs, its a JavaNG/Java3/BetterJava language (eg. Groovy). If the language has its own APIs, its a BeyondJava language (eg Fan, Scala).

All opinions welcome on Fantom and the BetterJava to BeyondJava boundary!