A first look at Gavin King's Ceylon

Gavin King brought us Hibernate and Seam. Now he wants us to drink the Kool-Aid -- or rather the Ceylon tea -- once more

Page 3 of 4

Typing in Ceylon
Ceylon is a strongly and statically typed language like Java. In fact, it is more strongly and arguably more statically typed than Java. The one "loosening" is that types do not have to be declared on references in advance of their first use. For example, I could type:

value header = contentType("text/html", utf8);

After this line the value reference header is a Ceylon string type. Notice I said "value reference" -- it's essentially the same as final variables in Java. They cannot be changed. If I wanted a reference that could be changed, I'd type:

variable header = contentType("text/html", utf8);

A bigger issue with typing is the way nulls are handled. It would be very difficult to get a NullPointerException in Ceylon. The type system requires you to explicitly handle nulls, which are, in essence, a type themselves.

Ceylon gives you tools to do that, but they may not be entirely intuitive while you are simultaneously thinking in Java or JavaScript. If I wanted to allow nulls, I could type a value like this:

Contact? contact = getContact(id);

someMethodThatDoesntHandleNulls(contact); //compile error

If I wanted to pass that to a method that doesn't handle nulls, I would need to use the exists keyword. For example, I could do this:

Contact? contact = getContact(id);

if (exists contact) {


} else {



Alternatively, I can use else like this:

String name = request.parameter("contact[name]") else "";

Ceylon actually supports multiple types for the same reference. For instance, I can have a type that is both Contact|Person. In fact Contact? is actually a shorthand for Contact|Null.

An emerging SDK
While porting Granny to Ceylon, I ran into multiple bugs; granted, most of these were in the brand-new HTTP server module. Commendably, these were all fixed very quickly by the Ceylon developer community -- in some cases, within an hour of reporting the bug. However, these are not edge cases; they are basic tasks like not hanging the thread after each delete request and handling contentType headers that contain the character set. When I say this is a "first look" and Ceylon is not ready to be the basis for your mission-critical project, I really mean it -- even if you're a Hipster Hacker.

The Ceylon APIs also presently lacks the superintuitiveness of, say, Ruby. For instance:

AsynchronousEndpoint {

   path =  startsWith("/scripts.js");

   service = serveStaticFile(".");


The argument to serveStaticFile is the relative path to prepend in front of whatever is in path. That is, the path is the argument to the thing with File and the file is what is in path.

Also, both strings and iterables have "last" members. In the case of a string, it refers to the last character. In the case of an iterable, this refers to the last element. That isn't overly confusing, unless you think of some of the places you might use them together, such as a split function. I swapped a split for a span, and suddenly I had type errors telling me I couldn't parse a character as an integer. It took a while to find the errant last.

| 1 2 3 4 Page 3