Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News Ceylon JVM Language

Ceylon JVM Language

Leia em Português

This item in japanese

Given as a talk at QCon Beijing (which was sold out), Gavin King presented the Ceylon programming language, which he has been working on at Red Hat for the last couple of years. The news was picked up via twitter, and now a number of sites are reporting it, including Lambda the Ultimate, Slashdot and Reddit and YCombinator Hacker News. As a result, Gavin has posted a a post specifically on Ceylon with references to the presentations that caused the stir. He also makes clear that it was never designed as a Java killer:

Nevertheless, I should make a few comments. First, I never billed this as a Java Killer or the next generation of the Java language. Not my words. Ceylon isn't Java, it's a new language that's deeply influenced by Java, designed by people who are unapologetic fans of Java. Java's not dying anytime soon, so nothing's killing it.

As a JVM based language, Ceylon will compile down to bytecode to run on top of the JVM and with Java classes. It has a more restricted form of generics than Java has (no wildcard generics) and supports contra/co-variance in method parameters and return types. This allows Ceylon to perform implicit casting with method return types, although there is no explicit cast operator. Further, since methods cannot be overloaded, there is no need to have methods with multiple types. Keywords in and out on parameters indicate their contra/co-variance support. There's nothing to prevent Ceylon being cross-compiled to other VMs, but the JVM is the initial focus.

Ceylon also introduces named and default arguments for methods, which are a key use case (in Java) for overloaded methods. Methods can also take methods, creating higher-order methods (or higher order functions). Everything is typed (number literals are not distinguished from object types) although the void type is represented as a keyword.

For Java users, many keywords have been changed; for example, instead of implements for interfaces, you now have satisfies. Other keywords have been replaced as well; public becomes shared, with protected and private unused; abstract becomes formal and actual is used for providing implementations of specific interfaces. You can combine interfaces with & instead of , separated lists.

Some operators have been provided; the <=> operator is a shorthand for Comparable's compare() method, whilst == is a synonym for equals(). Some operator overloading is allowable; for example, > is translated to Comparable.largerThan(), which can then be overridden by a specific type. The set of operators cannot be extended (unlike Scala, which permits methods to have non-ASCII names) – but the ones that exist can be overridden by implementation.

There's no null in Ceylon; instead, an Optional type provides an instance of an object, as well as using a type to indicate that it may be optional. The ? suffix on a type is shorthand for an optional value, so String? is a shorthand for Optional<String>.

Ceylon also provides mixin inheritance, as Scala, by allowing methods to be implemented in an interface, although initialization is not allowed. (Some of the project coin for Java 8 may have default methods which provide the same kind of behaviour.)

As many commenters have asked: Why not just use Scala? Gavin has specifically responded to this:

Scala is an interesting language and it's one of several languages that influenced Ceylon. We looked closely at Scala, but we collectively concluded that it wasn't the right thing for us. Personally, I find that Scala's type system is simply more complex than I want or need.

Since Ceylon doesn't support casting, a new keyword case (is...) has been added to a switch statement, which provides typesafe casting to a particular type. If the case block is true, then the body of the case block sees the narrowed type of the original object. If it is not of that type, then you don't execute that block of code.

The keynote presentation also alludes to modularity (a feature missing in Scala as well) but provides no information as to how modularity is handled. It does eschew both Maven and OSGi as “over-complex”, along with synchronization. (See below for Gavin's responses on these.)

Several commenters have identified specific issues with the presentation; for example, “Java is joined at the hip with XML” is factually incorrect and “There is simply no good way to define a user interface in Java” appears to be conflated with ease of use of libraries. Some Ceylon examples show how a user interface might be created in a declarative style similar to JavaFX, though GUI user interfaces are frequently created in other technologies. Others have lambasted the fact that the syntax for defining an in-line function, cited as “stolen from Smalltalk” bears no resemblance to the Smalltalk syntax for blocks. Although both are valid points, these are criticisms of the presentation rather than the language itself.

The future is still open for the Ceylon project, and the presentation was referenced earlier than the materials behind the project were made available. As the conclusion notes:

My team has spent the past two years designing what we think the language should look like, writing a language specification, an ANTLR grammar, and a prototype compiler
  • You can’t write code in the language just yet!
  • We plan an initial release of the compiler later this year

InfoQ reached out to Gavin to find out more.

InfoQ: There are a lot of comments comparing Ceylon to Scala. Where do you see the key differentiators are between the two languages, apart from the fact that Scala allows non-ASCII based functions?

Gavin King: Well, Scala is an interesting language, and is one of the languages that influenced the design of Ceylon. But there are certainly some big differences in emphasis.

Ceylon code is supposed to be readable to people who aren't Ceylon programmers. We've avoided syntactic constructs that we think hinder readability. For example, we avoid the use of cryptic punctuation where words would be better. And we're not going to support true operator overloading. We want to see plain, readable code, not executable ASCII-art.

One important force that helped make Java so successful was the things Java left out. But you need to be very smart here: Java's decision to leave out higher-order function support was enormously harmful. Now, obviously the Scala team have gone down a very different path here and have created a very feature-rich type system. As a general rule I would prefer to solve my problems with fewer, more general constructs, than with more, less powerful constructs.

I've invented some interesting things to make possible a statically-typed metamodel. What I mean is a typesafe version of reflection. I'm not aware of any other language that provides this, though it's possible that it has been done before in some research language that I don't know about. there's no overloading. There are no existential types. And there's no Java-style "null" hidden anywhere in the language specification. All these things would be useful for the interoperability scenario. But they're all otherwise quite harmful in terms of complexity. Oh and, generic type arguments are going to be reified! This opens up some very cool possibilities, but also slightly harms interoperability.

Because we're planning a whole new SDK, Ceylon doesn't make as many concessions in the type system to Java interoperability. In some cases, Java interoperability is going to suffer as a result of that. (Hopefully not too much!) For example, there's no overloading. There are no existential types. And there's no Java-style "null" hidden anywhere in the language specification. All these things would be useful for the interoperability scenario. But they're all otherwise quite harmful in terms of complexity. Oh and, generic type arguments are going to be reified! This opens up some very cool possibilities, but also slightly harms interoperability.

Finally, a major goal of the project is to provide a consistent, elegant, visually appealing syntax for annotations and for defining user interfaces and structured data. You can think of this as support for "declarative" programming, if you like. Now that Oracle have walked away from JavaFX, Ceylon is going to be the language for UI developers!

InfoQ: You note that Maven and OSGi are harmful; what support does Ceylon have for modularisation?

Gavin King: We'll take advantage of a well-defined source and module repository specification to integrate modularity into the toolchain all the way from compiler to IDE to runtime. When you have a more controlled environment, you can get away with much simpler tools. We're basing the module runtime on a project called JBoss Modules that will also form the core of JBoss AS 7. JBoss Modules is a super-simple, cut-down module system, far simpler than other solutions in the space.

InfoQ: Similarly, you note that every object is a semaphore (hence the 'synchronized' keyword) - what plans are there for Ceylon to support multi-threading and locking primitives?

Gavin King: I strongly believe that concurrency, at least until some kind of revolution comes along, is something that libraries should solve. The language doesn't need built-in concurrency primitives. There are a number of good competing patterns for handling concurrency - everything from actors to STM, and the language should make it possible to write libraries that implement these patterns.

InfoQ: You note that Java is joined at the hip with XML - but that's not true of the language; rather, frameworks like Spring utilise XML frequently. Is this what you meant?

Gavin King: I mean that there is no way to elegantly define a user interface, or any other static hierarchical structure, within the language itself. Therefore frameworks have to take one of two paths: define hierarchical structures using procedural code (Swing, Wicket) or resort to XML (JSF and many others).

InfoQ: Why is 'void' a keyword rather than a member of a type?

Gavin King: There is in fact a type called "Void", which turns out to be the return type of a "void" method, but lowercase "void" is a keyword. The reason for that is to indicate to the compiler that no "return" statement is required in the method definition. Note that Ceylon represents some concepts that are part of the language specification of most languages (for example, numeric types, null values, function types) within the type system itself. That's why the type system itself needs to be significantly more powerful than Java's.

InfoQ: For enumerated subtypes, is the set of subtypes a closed set? In other words, given class Node of Branch | Leaf, can I create a third subclass of Node?

Gavin King: No. The purpose of the "of" clause is to tell the compiler that these are the only subtypes, thus letting the compiler validate "case" statements which enumerate the subtypes of a type. If you can think of this stuff as a very convenient way to implement the visitor pattern without losing type safety.

InfoQ: For contra/co-variant types, is using keywords 'in' and 'out' (which have connotations in other programming languages as parameters which return by value) sensible? Will this not confuse developers who are used to 'in' and 'out' parameters in other languages (as distinct from understanding co/contra-variant types, which is useful)?

Gavin King: So we recently noticed that the C# team has independently come up with the exact same syntax, which made me feel pretty confident about it. I certainly think it's much, much better than "+" and "-". Another option would be "produces" and "consumes", but that's going to be very verbose if you have several type parameters. Better to keep it snappy, I think.

InfoQ: You're using 'satisfies' but still using nominative subclassing as per Java interfaces; what's the benefit of introducing the new keyword here?

Gavin King: Java is irregular here. In a class definition, the list of one or more interfaces follows the keyword "implements". In an interface the list of one or more interfaces follows the keyword "extends", which by coincidence may also appear in a class definition where it means something completely different (it is followed by a single class). Ceylon is regular. Lists of types always follow "satisfies". The keyword "extends" is always followed by an expression that instantiates the superclass.

We think syntactic regularity is very important.

InfoQ: Finally, what is the plans for getting this out into the open (other than e.g. QCon)? Are you going to make it available via GitHub?

Gavin King: Yes, once we're ready with the M1 compiler release, it will all be on GitHub. But I don't really want to release the grammar and type checker without having the backend to go along with this. To be honest, I wasn't expecting this to hit Slashdot quite so soon ;-)

The presentations are available at: introducing project Ceylon and the Ceylon type system. What do you think of Ceylon?

Rate this Article