Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

A first look at Gavin King's Ceylon

Ceylon's Milestone 5 release showcases a promising but still young language

  • Print
  • Feedback

Page 2 of 3

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) {

 someMethodThatDoesntHandleNulls(contact);

} else {

 doSomethingElse();

}

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.

Moreover, there is a matcher (above) on path but not on "method" forcing me to write something like this:

void contacts(Request request, Response response) {

if(request.method.equals("GET") &&

       request.path.equals("/contacts")) {

contactsGet(request, response);

} else if (request.method.equals("GET") &&

               request.path.startsWith("/contacts")){

contactGet(request, response);

} else if (request.method.equals("POST")) {

contactsPost(request, response);

} else if (request.method.equals("DELETE")) {

contactDelete(request response);

} else if (request.method.equals("PUT")) {

contactPut(request, response);

} else {

}

}

This is especially glaring in a language that's generally less verbose yet clearer. More important, this is the kind of code monkey stuff I hate to write -- and why we have interns.


  • Print
  • Feedback