Help

So Marc Richards and then slashdot picked up on my presentations at InfoQ China. I wasn't quite expecting this level of exposure at this point, and I imagine that things will quiet down pretty quickly at least until we do an initial release of the compiler. All we have right now is a specification, an ANTLR grammar, and an incomplete type checker. Work on the backend bytecode generation is just beginning (though we'll be able to reuse a bunch of code from javac).

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.

So why a new language? Well, we've been designing and building frameworks and libraries for Java for ten years, and we know its limitations intimately. And we're frustrated. I'm not going to recap all the frustrations here. (I've listed some of them in the first presentation.) But I guess I should mention that the number one technical problem that we simply can't solve to our satisfaction in Java - or in any other existing JVM language - is the problem of defining user interfaces and structured data using a typesafe, hierarchical syntax. Without a solution to this problem, Java remains joined at the hip to XML.

But much of our frustration is not even with the Java language itself. The extremely outdated class libraries that form the Java SE SDK are riddled with problems. Developing a great SDK is a top priority of the project.

On Slashdot, several commenters argue that creating a whole language and SDK from scratch is an enormous undertaking. Well, we're really not starting from scratch: we can reuse an enormous amount of code that is already available under open source licenses in the Java ecosystem. Just think of what's reusable from Open JDK, JBoss, and Eclipse! It's not a requirement that the entire SDK, compiler, and IDE be implemented in Ceylon. And it's not an enormous undertaking for a company of Red Hat's size. And, of course, we don't want to do this on our own. A project like this isn't even interesting unless it's a community effort.

Here's the presentations that caused this fuss:

UPDATE: If you're interested in knowing more about the language, please check out the tutorial Introduction to Ceylon.

127 comments:
13. Apr 2011, 14:28 CET | Link

Interesting approach, look clean and enough Java-like to ease the possible migration. The internal-like-DSL syntactical scoped support is also interesting.

Maybe the Pascal assignment may look a bit odd additional to all the unnecessary new keywords (shared? for public..) and attributes (doc? by?)... I'm also wondering how the integration with Java APIs will work. (see Scala, Groovy, JRuby....).

Anyway, just keep the details coming ... the JVM seams to be in a continuous revival lately ;)

To be easily accesible, I took the chance and shared the presentations on Slideshare: Introducing the Ceylon Project - Gavin King presentations at QCon Beijing 2011

ReplyQuote
 
13. Apr 2011, 14:37 CET | Link
Daniel

As many others, I'm interested why you think Scala isn't quite the language you were looking for.

13. Apr 2011, 14:51 CET | Link
Steven Boscarine
The sales pitch sounds great. Everything you described sounds like a great alternative JVM language. I can't wait to "kick the tires."

The thing that scared me initially was the ': =' operator...as at least 1 slashdotter pointed out, hitting shift and a key with your pinky is begging for a Repetitive Stress Injury. However, in reading your slides, I see that this is for mutable assignments.

If your mutable variable declaration requires the keyword 'variable,' why do you need a different operator as well?

 
13. Apr 2011, 16:05 CET | Link
Mark

To me, this looks much nicer than Scala from the first impression (I haven't used Scala, just Java and Csharp).

 
13. Apr 2011, 16:07 CET | Link
Mario
I wasn't quite expecting this level of exposure at this point, ... All we have right now is a specification, an ANTLR grammar, and an incomplete type checker.

Please don't rush it. We will try to survive with Scala in the meanwhile.

Seriously ... give up :)

 
13. Apr 2011, 16:07 CET | Link
Daniel wrote on Apr 13, 2011 08:37:
As many others, I'm interested why you think Scala isn't quite the language you were looking for.

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, with several features I think actually harm understandability/readability, and I find its syntax a bit of a dog's breakfast. (Oh and I guess there's way too much use of cryptic punctuation where words would be clearer and more readable.)

We're trying to live with a lot less language features than Scala. Leaving stuff out is, in and of itself, often a Good Thing. And we think it's important to have a very regular, visually pleasing, readable syntax.

Interestingly, Scala takes much more from ML/Haskell than Ceylon does, but whereas I think I can imagine myself getting into writing code in Haskell or even ML, I just don't feel the same way about Scala. I guess I just really don't feel that the whole language really hangs together the way Smalltalk or Haskell hang together.

But look, that's just a very personal view, and I simply don't want to get into criticizing Scala or arguing back and forth about specific language features. Ceylon is a quite different language and stands or falls on its own. And clearly Scala has one incredible selling feature that we simply can't match right now: an actual working compiler ;-)

 
13. Apr 2011, 16:07 CET | Link
and if not scala meet your need, what about Groovy++? Java like Groovy syntax, but staticly typed. and for parallel programming you can use GPars. I'm big fan of your project but yet another JVM language seems much more like a step aside (if it is not a step backward).
 
13. Apr 2011, 16:12 CET | Link
Mario wrote on Apr 13, 2011 10:07:
I wasn't quite expecting this level of exposure at this point, ... All we have right now is a specification, an ANTLR grammar, and an incomplete type checker. Please don't rush it. We will try to survive with Scala in the meanwhile. Seriously ... give up :)

Wow, you've seen a few slides, which partially cover a subset of the language, and you already know it's not worth doing? What if I'm coyly holding out on a couple of killer language features because I didn't have time to talk about them in two hours?

 
13. Apr 2011, 16:13 CET | Link

BTW, who else have been involved with this?

 
13. Apr 2011, 16:14 CET | Link
Mario

http://twitter.com/quelgar/status/58068573419085824 http://twitter.com/channingwalton/status/58138378260066304 http://twitter.com/ptrthomas/status/58127391339446272 http://twitter.com/dnene/status/58147223942332416 http://twitter.com/debasishg/status/58150799116738560 http://twitter.com/mariofusco/status/58159004077142016 http://twitter.com/mariofusco/status/58165368874737664

 
13. Apr 2011, 16:18 CET | Link
and if not scala meet your need, what about Groovy++?

Groovy and Ceylon are very different languages to even though they have a quite similar visual look (due to the shared Java heritage).

 
13. Apr 2011, 16:25 CET | Link

Mario, anyone who is forming conclusions about any language by reading a few slides, is by definition beclowning himself. Any anyone forming conclusions about a language by reading one-line tweets by guys who formed conclusions about a language by reading a few slides is double-beclowning himself. ;-)

 
13. Apr 2011, 16:55 CET | Link
Mario

Maybe, you're right. But what it's doing to himself somebody who spent 2 years to design a language in an ivory tower (just design, not implement at least for my current understanding) and after that is also not interested to reactions of other developers to his work?

 
13. Apr 2011, 17:51 CET | Link
Mario wrote on Apr 13, 2011 10:55:
Maybe, you're right. But what it's doing to himself somebody who spent 2 years to design a language in an ivory tower (just design, not implement at least for my current understanding) and after that is also not interested to reactions of other developers to his work?

Oh, I'm very interested in constructive criticism! Do you have some?

 
13. Apr 2011, 18:08 CET | Link
Mario

1. To write in your slides that Java syntax is based on math is just ridiculous. 2. Oversimplification of the public/protected/private access/visibility levels 3. Tons of questionable new keywords like shared, satisfies, assign, variable, local ... when all others modern languages clearly go in the opposite direction. 4. Type system actually looks more complex and less powerful than the Scala one. 5. Closure syntax is awful. 6. I don't see one single evident reason why I should prefer this over Scala,

13. Apr 2011, 18:50 CET | Link
Anonymous
You are supposed to use different hands for the shift key and the the shifted key, Then, using the shift key often doesn't hurt -- otherwise all German speakers would have that problem.

I would, however, like to have a programming language without brackets, curly braces and back slashes, because these are really awkward to type on an international keyboard.
 
13. Apr 2011, 19:00 CET | Link
1. To write in your slides that Java syntax is based on math is just ridiculous.

Ridiculous? Interesting. I studied mathematics (not computing) at university, and I've always found Java's syntax much more familiar than say Haskell or ML. And certainly much more familiar than lisp. Perhaps I'm the only one.

2. Oversimplification of the public/protected/private access/visibility levels

This is an extremely interesting and deep discussion, but since you're clearly not entering the conversation with a sufficiently open mind, we're not going to have it here. Suffice to say we spent a lot of time going back and forth on this, and I'm now convinced that the simpler model is ultimately superior. There are some things you can do with public/protected/private that you can't do with shared, and there are some things you can do with shared that you can't do with public/protected/private. But one annotation instead of three is a pretty major simplification. (It's also much more regular when you start thinking about the block structure of the language.)

3. Tons of questionable new keywords like shared, satisfies, assign, variable, local

Well,

  • the shared annotation is not a keyword, and it replaces 3 keywords in other similar languages,
  • the keyword satisfies replaces implements and is more regular,
  • the keyword assign is a new keyword, but serves the same role as 2 keywords get and set in C#,
  • the variable annotation is not a keyword,
  • the keyword local is a new keyword, but serves the same role as 3 keywords def, val and var in Scala.
when all others modern languages clearly go in the opposite direction.

I don't see any particular trend for more or less keywords in recent languages. Nor do I consider it an especially useful metric for judging programming languages. However, it is true that Ceylon has about 15 fewer keywords than Java.

(I would note that if you count the number of keywords that Scala uses to express the concepts listed above then it turns out that Scala, which you like, has more keywords than Ceylon.)

4. Type system actually looks more complex and less powerful than the Scala one.

Well, it's certainly not more complex. Indeed, it's simpler. It is less powerful in certain ways (no existential types or structural typing, a simpler mixin inheritance model, no true operator overloading, etc). On the other hand it's more powerful in other ways (reified generics, a typesafe metamodel).

5. Closure syntax is awful.

What precisely are you calling the closure syntax? You mean the syntax for anonymous functions? You're objecting to stuff like the following - copy/pasted from the language spec:

assert ("x must be zero") that (x==0.0);

return when (x>100.0) then (100.0) otherwise (x);

repeat (3) times { writeLine("Hello!"); };

Natural[] cubes = list (30) containing (Natural i) (i**3);

String[] names = from (people) select (Person p) (p.name);

Boolean adults = forAll (people) every (Person p) (p.age>=18);

Float total = fold (items, 0.0) using (Float sum, Item item) (sum + item.quantity*item.product.price);

Please translate the above method invocations into the proposed closure syntax for Java 7 and include the result in your reply. :-)

I always really liked this style of method invocation in Smalltalk. I admit it can be a bit off-putting at first for some folks with a Java/C background, even though it looks very much like the built-in control structures, but even Groovy and Scala feature something a bit similar. Honestly, I think this stuff is fair game for debate within the community. I find it very readable, but if I'm the only one, I'd be happy to drop it.

6. I don't see one single evident reason why I should prefer this over Scala,

Ah well, since that's a statement about yourself, it's not really open to debate, But seriously, why all the hate? Just get out of the wrong side of the bed this morning?

 
13. Apr 2011, 19:45 CET | Link
Mario
6. I don't see one single evident reason why I should prefer this over Scala,
Ah well, since that's a statement about yourself, it's not really open to debate

Ok, let me rephrase this. Being a Scala developer, could you tell me which are in your opinion the reasons why I should consider Ceylon instead? (I am speaking of Scala both because it's the language I know better together with Java and because it's statically typed like Ceylon, but feel free to enlarge the discussion to other languages like Clojure or Groovy if you want)

 
13. Apr 2011, 20:07 CET | Link
Ridiculous? Interesting. I studied mathematics (not computing) at university, and I've always found Java's syntax much more familiar than say Haskell or ML. And certainly much more familiar than lisp. Perhaps I'm the only one.

I hate to say it, but yeah, that's pretty much the case. As I'm sure you're aware, Java's syntax comes from C, which in turn draws heavily on Pascal and FORTRAN. Neither of these were designed to be mathematical expressions. In fact, their formal origins are in providing a textual description of a Von Neumann machine. While this is clearly a mathematical structure, it's also a very complicated one and not the preferred model when dealing with computation from a theoretical perspective.

To claim that a syntax is mathematical, one is asserting that analysis of the syntax (and by extension, semantics) is formally tractable and produces useful and interesting results. This is not the case with Java (incidentally, it's not the case with Scala either). Theorists have had to create a restricted, featherweight Java in order to make any progress in understanding the language from a formal perspective. That's a pretty solid indication that the syntax is not very mathematical.

Another way of looking at mathematical syntax would be to say that the syntax is amenable for expressing declarative mathematical theorems. An example of this in Haskell would be the ease with which Haskell can encode the monadic laws in their most general form. Again, this is an area where Scala falls short, but it's still lightyears beyond Java, which struggles to even express the basics of simple addition in the context of non-primitive numeric types.

By any standard, Java's syntax is industrial, verbose and generally quite battle-hardened, but it's anything but mathematical.

Well, it's certainly not more complex. Indeed, it's simpler. It is less powerful in certain ways (no existential types or structural typing, a simpler mixin inheritance model, no true operator overloading, etc). On the other hand it's more powerful in other ways (reified generics, a typesafe metamodel).

Scala actually has optionally reified generics via typeclasses, which is a substantially more powerful way to do it. It also avoids introducing an additional mechanism to accomplish the same thing.

I really think that calling Ceylon simpler than Scala is a bit of a stretch. The word itself is very subjective, so I'm not sure that arguing the point is going to yield anything useful, but it's still worth bringing up. Ceylon does appear to lack higher-kinds, existential types and (critically) typeclasses. Admittedly, these are very complex features of the type system. However, they also turn out to be extremely essential to meshing the object-oriented and functional paradigms. I believe you're going to run headlong into this when you try to build Ceylon's collections library. You will either end up with very few utility methods (the approach Java took), rendering collections far less useful, or you will have a proliferation of utility implementations, most of which return the wrong type (the approach Scala originally took, and later fixed in Scala 2.8).

So you've omitted some features that are in Scala's type system, but you've also added several big ones. Reified generics are very significant, and they basically preclude you from ever implementing higher-kinded or existential types. They also add a non-trivial amount of complexity to the type system. Additionally, primitive union types (which I actually like, btw) are another addition. Scala sort of has these implicitly through ADTs, but not quite.

There really isn't enough information out there for me to argue any further on this position, but from what I've seen, Ceylon isn't fundamentally any simpler or more orthogonal than Scala, quite the opposite. It's certainly less powerful in some ways (typeclasses, higher-kinds), but more importantly it has a number of specifically-targeted language features (e.g. reified generics) which could have been implemented via a more general mechanism.

 
13. Apr 2011, 20:12 CET | Link

Well, I think I already responded to that question, and I'm really not going to be drawn into some kind of flamewar vs. Scala. If you love Scala so much, use Scala. End of story.

 
13. Apr 2011, 20:39 CET | Link
Reed Roberts

Well I like most of what I have seen so far.

One slight nit, for a language that is intended to be less verbose, I think I would tire of typing out 'variable' much of the time. I hope there is a shortcut.

The big surprise was one constructor per class. That could hurt. Optional parameters can help, but constructors with mutually exclusive parameters are not uncommon.

It will be interesting to see how this constraint affects the design of the SDK.

 
13. Apr 2011, 20:43 CET | Link
Alex

Hi,

I often tought we could really need a new modern language based on what is good in Java and fixes things that are broken.

I really really hope that in Ceylon all classes will be final by default and all methods and attributes as well. So in order that something is modifiable you must first declare it as such. There is so much code where there's no final keyword for things that really need not to be modifiable / overridable / subclassable. Of course, it could be that a developer makes a false prediction and thinks his class needs not to be subclassed but in practice in turns out it must be. So then clients cannot subclass it. It would then be cool to have a force keyword which would allow to subclass even classes that are not declared as subclassable (of course giving you a warning).

13. Apr 2011, 21:02 CET | Link
John DeHope | johndehope3(AT)gmail.com

Stop feeding the haters. I don't think you need to even reply to them. If you get bogged down in syntax/language wars, you'll never make any progress. You have the right goals and guideposts in mind (at least I think you do) so just keep following them. If you spend time answering every single guy with an axe to grind, you'll never get anywhere.

Also, I hate the JVM, and wish you'd use LLVM as the back end so I can run this thing on the CLR :)

 
13. Apr 2011, 23:27 CET | Link

The syntax feels quite groovysh. Well, if there'd be fast retargetable compiler and awesome tooling.. hell, why not!

 
13. Apr 2011, 23:37 CET | Link
well..i was wondering what you were working on these days :-)

Just my 2 cents :
Through the years I used a lot of different languages. Starting with java and moving on to groovy,scala,… I just pick what seems best for my home-projects or POC's. At work I'm forced to use java but I'm very displeased with the lack of progress, but hey..guess that's the price you pay when a language is used in 'enterprise' systems. (note the sarcasm)
When using scale the first time I had some trouble just reading those seemingly awful peaces of code..I just was't used to program like that. After some time I really started to enjoy it and now i love it.

What i mean to say is that at first glance everything seems weird and obscure but after a while its pretty straightforward.

We all must try to contribute something, somewhere, somehow to make our lives easier. When reading some of the hate-comments I can only think "so..and what have you done for us". Nothing is perfect, every path has some downsides. Face it..there will never be a perfect language to express all your specific needs in the most clean/readable way possible.

So Gavin, I must thank you for giving it a try and hopefully something great comes out of it or some concepts get included in some more mature JVM-language. And to all the haters, at least they are trying to make our work easier and more productive. Be more supportive of change and give some pointers that are helpful instead of bashing. Even simple ones like:
1. 'variable' keyword is to long use var instead
2. to promote immutability make it harder to make something mutable (F# like syntax) : mutable keyword


good luck to you! :-)
 
14. Apr 2011, 00:37 CET | Link
Mario

7. Optional only adds useless verbosity. Nothing comparable with scala Option. You don't have a clue of what monads are, don't you? 8. One single constructor per class? Don't you think it's a big limitation? 9. No lambdas? No, thanks. 10. No implicits 11. What about concurrency?

14. Apr 2011, 00:42 CET | Link
R.S.
I think the response to Daniels question is not really giving any good reason apart that you do not like Scala. Fair enough, but hardly something that can convince anyone who base their decision on actual arguable criteria. Much of what you might think is complex in Scala is optional and can simply be avoided while Scala offers a lot of features for making things for the programmer actually much more easy. One of which being type inference. From the slides I have seen it seems that not even this is supported in Ceylon so one has to actually write "Complex x = Complex(1.0)". Another advantage of Scala is the ease of migrating from Java to Scala and mixing legacy Java classes with new Scala code.

So, when introducing a language that should be picked up by others, I think you cannot simply ignore existing alternatives and wave them away by a short statement about your personal preference. What is needed are good arguments in which respects Ceylon can be a better tool for programmers than e.g. Scala or other alternatives. So far, I have a hard time seeing any, but maybe that is just because they were not pointed out well enough yet?
 
14. Apr 2011, 01:10 CET | Link
I hate to say it, but yeah, that's pretty much the case. As I'm sure you're aware, Java's syntax comes from C, which in turn draws heavily on Pascal and FORTRAN. Neither of these were designed to be mathematical expressions. In fact, their formal origins are in providing a textual description of a Von Neumann machine. While this is clearly a mathematical structure, it's also a very complicated one and not the preferred model when dealing with computation from a theoretical perspective. To claim that a syntax is mathematical, one is asserting that analysis of the syntax (and by extension, semantics) is formally tractable and produces useful and interesting results.

Huh? You seem to be confused by this word syntax. When I'm talking about syntax I'm definitely not talking about formal origins, semantics or understanding the language from a formal perspective.

If your language uses f x y or (f x y) instead of f(x, y) to represent function application, it does not have the syntax that is taught to high school students and used by all engineers and most mathematicians and computer programmers. Ditto if it uses something like \\f x y -> ... to declare a function. This minor syntax detail alone is a powerful reason why fortran-like languages will remain for the forseeable future more popular than lisp, Haskell, ML, and friends.

Scala actually has optionally reified generics via typeclasses, which is a substantially more powerful way to do it.

Type classes are a very interesting, but slightly different feature. We've already figured out how to layer type class support over reified generics and the typesafe metamodel.

It also avoids introducing an additional mechanism to accomplish the same thing.

I don't see how type class support, in itself, solves the problem of letting me do if (is List<String> listOfObject), but perhaps I'm missing something.

Ceylon does appear to lack higher-kinds, existential types and (critically) typeclasses

It certainly lacks higher kinds, existential types, (and also structural typing). And even though it will almost certainly eventually feature type classes, GADTs and a couple of other sexy things that I won't go into here, it will still be a simpler type system than Scala :-)

However, they also turn out to be extremely essential to meshing the object-oriented and functional paradigms. I believe you're going to run headlong into this when you try to build Ceylon's collections library.

I very much doubt that we'll need higher kinds or existential types to implement the collections framework.

Reified generics are very significant, and they basically preclude you from ever implementing higher-kinded or existential types.

Not a problem. :-)

There really isn't enough information out there for me to argue any further on this position, but from what I've seen, Ceylon isn't fundamentally any simpler or more orthogonal than Scala, quite the opposite.

But, well, you haven't actually seen anything now, have you? You saw some slides I made for a general audience at a conference. You haven't seen the language specification. You have no idea about the full feature set. But you're already an expert and you already know exactly how it stacks up against your favorite language. And you're already tweeting to the world that I don't know what I'm talking about. Classy.

14. Apr 2011, 01:23 CET | Link
Much of what you might think is complex in Scala is optional and can simply be avoided

If a language feature is used in any of the class libraries or frameworks I'm dependent upon, or if any of my team members use the feature, I can't avoid it. This means that, in practice, it's never possible to completely avoid any language feature.

One of which being type inference. From the slides I have seen it seems that not even this is supported in Ceylon

It is supported for non-shared declarations. The local keyword may be used in place of a type. This is even mentioned in the slides.

From the slides I have seen it seems that not even this is supported in Ceylon so one has to actually write Complex x = Complex(1.0).

You can write local x = Complex(1.0);.

So, when introducing a language that should be picked up by others, I think you cannot simply ignore existing alternatives and wave them away by a short statement about your personal preference. What is needed are good arguments in which respects Ceylon can be a better tool for programmers than e.g. Scala or other alternatives. So far, I have a hard time seeing any, but maybe that is just because they were not pointed out well enough yet?

On the contrary, I'm quite happy to let the language speak for itself, and let folks make up their own mind by actually playing with the language once the compiler is ready. It's of course quite impossible to have a truly informed opinion about a language until you've actually tried to write code in the language.

 
14. Apr 2011, 01:37 CET | Link
7. Optional only adds useless verbosity. Nothing comparable with scala Option.

What are you trying to say?

Optional in Ceylon is extremely similar to e.g. Maybe in Haskell. The main difference is that the language provides special syntactic support for working with Optional.

You don't have a clue of what monads are, don't you?

I think I have a pretty good handle on what monads are, actually.

8. One single constructor per class? Don't you think it's a big limitation?

Definitely. Removing overloading is something I do with great misgivings. But overloading really does cause a lot of complexity, and we have some great alternatives to overloading for some common cases where overloading is used.

9. No lambdas? No, thanks.

Do you even understand the thing we have instead of anonymous functions?

10. No implicits

Well, we do in fact have implicit type converters in the language spec currently. I've been trying to convince myself we don't need them, but I've failed so far.

11. What about concurrency?

What about it?

 
14. Apr 2011, 01:44 CET | Link
1. 'variable' keyword is to long use var instead

We've so far avoided abbreviations. In practice the IDE will type this annotation name for me.

2. to promote immutability make it harder to make something mutable (F# like syntax) : mutable keyword

Well, giving the variable annotation a shorter name would make it easier to make something mutable, right? Hehe.

 
14. Apr 2011, 01:56 CET | Link
The big surprise was one constructor per class. That could hurt. Optional parameters can help, but constructors with mutually exclusive parameters are not uncommon

Yes, it will be inconvenient from time to time. Only time will tell how often.

Note that there are some overloading cases that can be handled by doing stuff like this:

void print<T>(T printable) 
        given T of String | Named {
    String string; 
    switch (printable) 
    case (is String) {
        string = printable;
    } 
    case (is Named) {
        string = printable.name; 
    }
    writeLine(string);
}

That code snippet is taken straight from the slides.

 
14. Apr 2011, 02:06 CET | Link
really really hope that in Ceylon all classes will be final by default

No, classes are open to extension by default. And there's actually no way to prevent a class being extended! But this is OK, since methods and attributes are final by default. So you can extend a class, but you can't actually break it.

and all methods and attributes as well. So in order that something is modifiable you must first declare it as such.

Exactly. Only methods and attributes explicitly annotated formal (like Java's abstract) or default (like C#'s virtual) may be refined.

There is so much code where there's no final keyword for things that really need not to be modifiable / overridable / subclassable.

Totally. Any safety feature should be on by default or it winds up being pretty useless. You would never know if an attribute is really truly mutable, of if the author simply forgot to make it immutable. Just like in Java where you never know if something is really truly meant to be package protected, or if the author just forgot to add the private modifier.

 
14. Apr 2011, 02:30 CET | Link
Peter

I really like a lot of the design decisions you made. I know from experience how you can't just evaluate a language from a list of features - you have to see how it all works together. For example, I was worried at first when I saw you weren't supporting lambdas, but it looks like your basic syntax is already concise enough that they wouldn't have much benefit. And only one constructor per class seems like a big limitation at first, but Joshua Bloch has been telling us for years to use static factory methods instead of overloaded constructors, and that really works just as well.

I have some questions about the flexibility of your operator polymorphism. Suppose I want to implement classes for (mathematical) vectors and matrices. I obviously want to implement the standard math operators for them, but the return types vary based on the arguments. For example, matrix*matrix is a matrix, but matrix*vector is a vector. Will there be any way to do that? Also, if v is a vector, I would want to be able to write either v*2 or 2*v, but it appears the latter would be interpreted as a method call on the object 2. Will there be a way to make that work?

I'm also wondering why you decided to create so many completely new keywords instead of using the same words other languages use for the same concepts: shared instead of public, satisfies instead of implements, formal instead of abstract, and so on?

 
14. Apr 2011, 02:56 CET | Link
Bryan

Gavin, was wondering what the difference was between '=' and ':='. Mutable and immutable object assignment operators? It sounds like the latter is doing a deep copy, but I'm not certain.

Is there something like a reference equality operator? And if so, does that mean "==" is syntax sugar for object.equals()?

Knowing what's intended for generics (please no type erasure,) concurrency, even thoughts on the Classpath would all be useful.

 
14. Apr 2011, 03:39 CET | Link
I have some questions about the flexibility of your operator polymorphism. Suppose I want to implement classes for (mathematical) vectors and matrices. I obviously want to implement the standard math operators for them,

Well, this is a bit of an interesting one. The thing about vectors and matrices is that their standard math operators are not really the standard operators of a ring.

but the return types vary based on the arguments. For example, matrix*matrix is a matrix, but matrix*vector is a vector. Will there be any way to do that?

Probably not. Note that matrix multiplication (and also vector product) are just not really multiplication in the sense of a ring. They don't obey the axioms of a ring, so they don't really fit into our model of *.

Also, if v is a vector, I would want to be able to write either v*2 or 2*v, but it appears the latter would be interpreted as a method call on the object 2. Will there be a way to make that work?

No, since there is no way to convert the arguments to the same type. All the binary operators are symmetric.

I'm also wondering why you decided to create so many completely new keywords instead of using the same words other languages use for the same concepts: shared instead of public, satisfies instead of implements, formal instead of abstract, and so on?

Well, there are some subtle differences that don't always come out in the slides.

For example, shared doesn't mean public. A shared member of a shared toplevel class is the same thing as Java's public. But a shared member of a non-shared toplevel class is like Java's package-private. A shared member of a nested class is visible to the block containing the class. The idea behind shared is to replace three annotations with just a single annotation, simplifying the whole visibility model.

The reason for formal instead of abstract is that Ceylon features the very interesting notion of polymorphic member classes, which may be formal. In fact, if you look carefully at the semantics of abstract in Java, it actually means two quite different things depending upon whether it appears on a class or on a member. Ceylon reuses abstract for abstract classes, the first sense of abstract in Java, but uses formal for the second sense.

The reason for renaming overrides is that the word is not an adjective, and doesn't read well when combined with other annotations. Also, actual is more symmetric with formal.

I explained the reason behind satisfies in the InfoQ interview. Basically, its for regularity. In Java, extends means something different - and has a different grammar - when it appears in an interface definition vs. a class definition. In Ceylon, satisfies and extends have very consistent interpretations (and grammar) across class, interface, and type constraint declarations.

 
14. Apr 2011, 03:51 CET | Link
Gavin, was wondering what the difference was between = and :=.

The := operator assigns a new value to a variable local or attribute. On the other hand, the specifier = is used to specify the value of a non-variable local or attribute. If a value is specified with =, it can never be subsequently respecified.

Ceylon encourages you to use immutable values as much as possible, and warns the reader of the code when you don't.

Hopefully you'll use assignment much less in Ceylon than in Java.

It sounds like the latter is doing a deep copy, but I'm not certain.

No.

Is there something like a reference equality operator?

Yes, ===.

And if so, does that mean == is syntax sugar for object.equals()?

Sugar for Equality.equals(), yes.

Knowing what's intended for generics (please no type erasure,)

Well, type erasure means two different things in Java. One is that that VM doesn't enforce type safety at runtime. We can't change that (at least not without massively harming performance), and I don't think it's really a big deal. The other is that type arguments are not available at runtime. We can, and will, fix that, and it is a big deal.

You could say something like: generics in Ceylon are erased by reified. But I'm not sure if many people would understand what that means.

concurrency

That's a job for libraries. We want to give you a choice: actors, STM, choose your poison.

even thoughts on the Classpath

No classpath. There is a well-defined module repository architecture and everything will be loaded by the built-in module runtime which is based on JBoss Modules.

 
14. Apr 2011, 04:49 CET | Link
Peter

And the reason for using Natural instead of Int or Integer like every other language in the world? :)

Oh, and if I ask really nicely, will you agree to support """ syntax for multiline string literals?

 
14. Apr 2011, 05:06 CET | Link
And the reason for using Natural instead of Int or Integer like every other language in the world? :)

Naturals are unsigned. Integers are also supported.

Oh, and if I ask really nicely, will you agree to support """ syntax for multiline string literals?

No, since regular string literals may be split across multiple lines. Don't see a need for two different quote conventions here.

 
14. Apr 2011, 05:58 CET | Link
Jeremy Norris | jnorris(AT)pattern73.com

Great work Gavin, I look forward learning more about this...

 
14. Apr 2011, 09:04 CET | Link

I think that during the discussions on whether Gavin knows Scala or not (see twitter/infoq/here - really guys, is this the proper level for language design discussion? I really like Scala, but why do you have problems with a new language?) somehow the really interesting and unique features of the language are missed.

Firstly, statically typed metamodel - it would be great to see how it works and some examples what can be done with it. Annotations in Java pushed metaprogramming one level higher, maybe this is the next step? I don't think there's something similar in other languages?

Secondly, initialization parameters in generics - I think this may be the key feature in developing a nice collections framework. Same as above, I'm not aware of other languages with such a feature?

Good luck with the project and waiting for a compiler to try it out :).

Adam

 
14. Apr 2011, 13:08 CET | Link
qammm

Your language seems to take quite a lot of inspirations from C#. Why don't you just implement a C# compiler for the JVM (or port one from http://stackoverflow.com/questions/988514/is-c-compiler-open-source)?

Even if you had a compiler, you would still need documentation, books, community for mass adoption. Things C# already has...

 
14. Apr 2011, 13:33 CET | Link
Sakuraba | saku(AT)raba.jp

Amazing stuff. My personal opinion is, that Scala will never be ready due to its complexity and because of the fact that it does not clearly position itself (attractive to academic FP-developers or to real-world people trying to get a job done).

It is great to see that we will soon have a commercially-backed alternative to Scala that will help us move forward off the old Java SDK cruft, because it is clear that Java cannot be evolved anymore at this point.

 
14. Apr 2011, 13:57 CET | Link
I'm very interested in constructive criticism!

No you're not. You were given constructive criticism and you dismissed it with a dishonest tactic. Whether you or I like it or not, there is a chronic display of naivety on display here. This is a rather unimportant matter -- we are all naive about many things. To be clear, the magnitude of this display is gobsmacking and there are many more constructive criticisms that could be articulated, but you're simply not interested.

What you have essentially done is stick your fingers in your ears in favour of ignorance. There comes a time when we must put aside our empathy as we cringe in embarrassment on your behalf and simply laugh.

PS: Failure to understand a concept is not permission to call it complex.

14. Apr 2011, 15:09 CET | Link
John DeHope | johndehope3(AT)gmail.com

One thing I'd like to hear more about in a futue presentation is the module system. Those of us outside the Java community may not be familiar with JBoss.

The explanation for why different keywords were chosen was great, thanks for that. I am sure you will have to repeat it many times in the future.

Regarding the various syntaxes for method calls... I get that you want to be able to define UIs in actual code, but do you need { instead of ( to do that? I share the goal, but I'm still not sure you need a different punctuation for it.

I completely love the straightened out type system. I mean I love it as much as I can without being able to code in it yet. Type systems seems to be a tar pit for also-ran languages like Scala and all the wacky functional languages like Haskell. In this area, especially at work, I much prefer a pragmatic approach, rather than an academic or pure one. I get that a lot of folks don't share this feeling. That's cool they can use languages with more extensive type systems. In this area I think it's more important what you leave out, rather than all the things your system can do.

 
14. Apr 2011, 15:26 CET | Link
PS: Failure to understand a concept is not permission to call it complex.

It's certainly not right to confuse lack of understanding with lack of understandability (or complexity), but I don't think anyone here is doing that.

OTOH, it's certainly reasonable to call a software solution more complex when it contains more features. That's just what complex means. Do you accept that much? If so, then surely you could concede the point that Scala has a more complex type system (or more feature-rich, if you prefer) than most other languages?

Of course, complexity can often be justified due to the difficulty of the problem(s) being solved. So identifying complexity only gets us halfway to a valid critique - we still need to propose a less-complex solution to the problem(s) before we can reasonably criticize the complex solution.

But it turns out that there are some folks (I won't speculate how many) who think that the problems they're interested in could be elegantly solved in a less complex programming language than Scala. And they consider lower complexity a thing in itself worth pursuing. (I guess I identify myself with this camp.) You may not agree withing these people - or perhaps the problems you're interested in are simply different problems - but what you can't deny is that there are some very smart serious folks saying this in good faith.

Unfortunately, I've noticed that some in the Scala community have the habit of responding to these people with variations on the claim that they are too stupid or perhaps ignorant to understand Scala. Tony, that's not going to wash here, since it's quite clear to everyone who's paying attention that the folks designing Ceylon do have a solid handle on how type systems work, and have in fact taken the time to study other languages and their type systems.

So if you want to continue this conversation, please respond with something a bit better than your above incoherent ad hominem. We're both intellectually curious, well-intentioned people trying to build great software for other developers, and we both understand the topics under discussion.

14. Apr 2011, 15:52 CET | Link
One thing I'd like to hear more about in a future presentation is the module system. Those of us outside the Java community may not be familiar with JBoss.

Well, I'm planning some blog posts about Ceylon, but I think the module system isn't quite the top priority, since there's a whole lot of interesting stuff missing from my slide sets (for example, member classes and member class overriding that I just mentioned). And the module system stuff is one area where the details are much less figured out. (Though we're quite advanced on the implementation side.)

The explanation for why different keywords were chosen was great, thanks for that. I am sure you will have to repeat it many times in the future.

No doubt.

Regarding the various syntaxes for method calls... I get that you want to be able to define UIs in actual code, but do you need { instead of ( to do that? I share the goal, but I'm still not sure you need a different punctuation for it.

Well, need would perhaps be putting it too strongly. But I certainly feel that the code is far more visually appealing that way. Especially once you start nesting callback method definitions inside named argument lists. To my eyes, it looks really ugly to have brace-delimited blocks nested inside parens.

I completely love the straightened out type system. I mean I love it as much as I can without being able to code in it yet. Type systems seems to be a tar pit for also-ran languages like Scala and all the wacky functional languages like Haskell.

Hrm, well, I think Haskell has a pretty great type system, actually. Not at all tarpitty.

In this area, especially at work, I much prefer a pragmatic approach, rather than an academic or pure one. I get that a lot of folks don't share this feeling. That's cool they can use languages with more extensive type systems. In this area I think it's more important what you leave out, rather than all the things your system can do.

I guess I agree in spirit... but on the other hand there is plenty of interesting work going on in the academic PL community, and we've certainly paid attention to that during the design of Ceylon. The Java world can't simply ignore all the things the FP community has been working on, since some of it is just plain useful.

 
14. Apr 2011, 19:28 CET | Link

I was hoping to get some clarity on the polymorphism of operator types. You stated in your slides that + is the equivalent of Numeric.plus()

If I understand this correctly, you're not just calling the method 'plus' but actually validating that the calling object is a Numeric before the operation takes place, and that the reason for this is to force the caller to satisfy Numeric so that you can prevent abuses of the operator being utilized in non-numeric contexts.

Did I get that right?

Are these operators implicit in the language or are they explicitly defined?

If they aren't explicit then why?

 
14. Apr 2011, 19:33 CET | Link
R.S.

One comment totally unrelated to the language itself: what's with all the secrecy and solitarity? What is the point of developing a language for years in secrecy without discussing this or getting early criticism and then unveiling it and expecting people to love it? Did you cooperate with anyone outside Redhat? This is not a new shooter game, not even a new library -- it is something that only makes sense at all if a large number of people adopt it and if it grows on your potential Ceylon fanboys. Even now, information about this project is extremely sparse and you often mention yourself that you do not talk about this or wont go into that. Maybe that will all change now, but I am pretty sure that a development model where Redhat just dumps a new language on the community will not go down well with most of the community.

14. Apr 2011, 22:33 CET | Link

Gavin, You don't get to invent an ad hominem then claim that you were a victim of it. There was no ad hominem prior to your invention. This is the second dishonest tactic that you have used. I invite you to stop.

I will have to repeat, you are not after constructive criticism and this is evident by:

  • Your dishonest response to Daniel.
  • There is ample opportunity for constructive criticism given the extraordinary ignorance on display here. I completely understand that you are not aware of the magnitude that I claim to see -- that's the point of pursuing intellectual discourse (seriously, try it).

You will probably be receiving more constructive criticism, even though you resent it, but after everyone stops laughing (empathy aside).

Some of us (though not me personally) are waiting for haha just joking guys!, but I think it is safe to say that no such thing is coming.

 
15. Apr 2011, 00:08 CET | Link
Mario
Optional in Ceylon is extremely similar to e.g. Maybe in Haskell. The main difference is that the language provides special syntactic support for working with Optional.

Meaning they are monads? Are at least you can concatenate them is some other way?

15. Apr 2011, 01:39 CET | Link

Since your second post here demonstrates that you've no interest in

I will have to repeat, you are not after constructive criticism and this is evident by:
  • Your dishonest response to Daniel.
  • There is ample opportunity for constructive criticism given the extraordinary ignorance on display here. I completely understand that you are not aware of the magnitude that I claim to see -- that's the point of pursuing intellectual discourse (seriously, try it).

Mate, nobody knows what you're talking about, and you're making an ass of yourself. What on earth did I say that was dishonest? And how would you even know that it was actually dishonest, rather than just e.g. honestly mistaken? What on earth did I say that was ignorant or naive? These are your words, that you've used in your first ever interaction with me, Without even first asking me to clarify whatever it is I've said that's bugging you. I mean, nobody here has even any idea of what it is that's bugging you. Really, that's just not grown-up behavior. It's not even regular internet-comment-thread-nonsense-behavior. It's more or less crazy behavior.

My comment about constructive criticism was in response to Mario. Daniel had not even posted at that point.

My actual response to Daniel just:

  • clarified what I meant when I talked about Java having a syntax based in everyday mathematics rather than the lambda calculus (this point from a slide set never meant for widespread consumption has been widely misunderstood by folks who probably aren't very interested in trying to read things according to the principle of charity)
  • mentioned that Ceylon will (probably) have type classes (that's not mentioned in said slide set)
  • mentioned that I don't think we will need existential types or higher kinds in the language

What here was dishonest or ignorant?

You will probably be receiving more constructive criticism, even though you resent it, but after everyone stops laughing (empathy aside).

Dude, trust me, you sound like a high school student. This isn't the way adults interact.

Some of us (though not me personally) are waiting for "haha just joking guys!", but I think it is safe to say that no such thing is coming.

Definitely not :-)

 
15. Apr 2011, 01:48 CET | Link
R.S. wrote on Apr 14, 2011 13:33:
One comment totally unrelated to the language itself: what's with all the secrecy and solitarity? What is the point of developing a language for years in secrecy without discussing this or getting early criticism and then unveiling it and expecting people to love it?

I mean, if anything, I would say we've gone public with this much too early. We should have kept it under wraps until we at least had the M1 release of the compiler.

If we would have come out and started taking in public about a bunch of totally half-baked ideas before even really knowing what we were doing, you would have criticized us even worse. I'm damned if I do (talk), damned if I don't.

Sometimes it's better to be able to just sit down and think about a problem with a clear mind without the need to be wasting time defending your ideas in public, etc. Just look at this train-wreck of a comment thread, and think about the time I'm wasting here responding to totally hostile comments from Scala fans.

I mean, it's simply not possible for a company like Red Hat to do an effort like this in a low-key way as I would prefer. I did a single presentation to an obscure conference in China, and next thing I know it's on Slashdot! At least at this point I know I have something defensible to defend against the inevitable avalanche of criticism.

 
15. Apr 2011, 01:52 CET | Link
Even now, information about this project is extremely sparse and you often mention yourself that you do not talk about this or wont go into that.

Right, because I have not prepared the necessary materials to properly socialize some things. If I just release everything we have written down right now, it's going to be completely misunderstood by folks not really trying to understand it or treat it charitably.

 
15. Apr 2011, 02:17 CET | Link
Ivan

We believe that the mathematical way is the normal way (the only way) for a programming language. But actually, thinking about DSL's and their deeply inclusion in the programming language's grammar is the indirect concern of people like Uncle Bob or Marin Fowler (and the so called Software Craftsmanship people). Code that really rocks! The project try to answer and solve old questions:

How to tell the difference between good and bad code? How to write good code and how to transform bad code into good code? How to create good names, good functions, good objects, and good classes? How to format code for maximum readability? How to implement complete without obscuring code logic?

Good luck Gavin. I wait for news.

 
15. Apr 2011, 06:22 CET | Link
Pseudonym | ajb(AT)spamcop.net
What language spec, if I may ask?

(I tried to reverse-engineer a first cut grammar from the slides, but there weren't enough examples, sadly.)
 
15. Apr 2011, 07:16 CET | Link

You should feel flattered, languages are designed all the time but few receive this kind of attention from just a few slides ;-) I think that if you introduced your team, people would have an easier time to understand the design decisions.

Since I have no Scala background, it's still a bit unclear to me how this fits into the ecosystem as a whole. In order for it to be popular, people need to be able to write business apps in it, that required use of e.g JPA. Wouldn't that mean JPA would have to be specified and implemented with a Ceylon API also?

 
15. Apr 2011, 07:31 CET | Link
Grzegorz Grzybek | gr.grzybek(AT)gmail.com

@Gavin

First - respect for trying to build something new and for your attempt to design a language (whole ecosystem?) from scratch.

Almost all discussion so far is about syntax, grammar and Scala/Groovy/C#/etc. similarities. I have different questions:

What would a language and SDK for business computing look like if it were designed today, with an eye to the successes and failures of the Java language and Java SE SDK?

Because I know your work and involvement in JavaEE, I'm sure you know that the business part in Java lies not in JavaSE, but in JavaEE. Do you want to build your own CeylonEE giant? Or, assuming you want to sell your work to the business, how are you going to re-use JavaEE with all its hacks involving:

  • static factories and methods (from your slides: Therefore, there’s no equivalent of Java’s static): javax.xml.ws.Endpoint.publish(String, Object), javax.mail.Transport.send(Message, Address[]), ...
  • all javax' FactoryFinders

You want to use existing JavaEE stuff (at least your own), do you? Whatever you'll do, what about community (Ceylon Community Process?), existing application servers (any place for them in your vision? unless JBoss has hidden ceylon deployers that will sweep all WebSphere, WebLogics and Glassfish (Glassfishes?) from earth), existing (JavaEE) tools and libraries?

There is a well-defined module repository architecture and everything will be loaded by the built-in module runtime which is based on JBoss Modules

You mean JBoss Microcontainer's deployments, JBoss Classloader/Classloading system, JBoss VFS?

regards Grzegorz Grzybek

 
15. Apr 2011, 07:58 CET | Link
Because I know your work and involvement in JavaEE, I'm sure you know that the "business" part in Java lies not in JavaSE, but in JavaEE.

Well, I'm not sure about that. I personally think the things that make it businessy are spread across the VM, the language, SE and EE. Though of course it would not be businessy were it not for the EE (or Spring) icing on top.

Do you want to build your own CeylonEE giant?

No, I think one of the things that most harms the Java world and poisons the Java community is the division into multiple platforms. Much better to divide things into much smaller modules that can be used piecemeal. I have always got the impression that the Perl and Ruby communities function much better because of how their code sharing mechanisms work.

To take one random example, something like JPA should be a module that can be used without reference to any specific platform.

As for giant, no, I am of the view that the actually useful bits of SE and EE are quite a lot smaller than either platform ;-)

Or, assuming you want to "sell" your work to "the business", how are you going to re-use JavaEE with all its hacks involving:

We will need to wrap a lot of things in a Ceylon-ified API. Some modules will consist of a thin layer of Ceylon over mature existing Java code. But some hacks might need to be sanitized out first, so that things can actually peacefully coexist on the module runtime.

You want to use existing JavaEE stuff (at least your own), do you?

I want everyone to be able to publish their technology on a central, politically neutral, module repository where everyone can easily get at it.

Whatever you'll do, what about community

I don't have a set idea. I would definitely like to set up some kind of independent group to steer the effort, but I also don't want to end up with something as semi-disfunctional as the JCP ;-)

You mean JBoss Microcontainer's deployments, JBoss Classloader/Classloading system, JBoss VFS?

No, that's JBoss 6 stuff. The new kernel of JBoss 7 (JBoss Modules) is significantly simplified.

 
15. Apr 2011, 09:58 CET | Link

Sorry, couldn't cope with the comment editor, so I posted my comments in my own blog: http://blog.pdark.de/2011/04/14/project-ceylon-successor-for-java/

(note: This is my 4th attempt to comment)

 
15. Apr 2011, 11:05 CET | Link
Grzegorz Grzybek | gr.grzybek(AT)gmail.com

@Gavin

No, I think one of the things that most harms the Java world and poisons the Java community is the division into multiple platforms. Much better to divide things into much smaller modules that can be used piecemeal. I have always got the impression that the Perl and Ruby communities function much better because of how their code sharing mechanisms work.

Maven (with all its pros and cons) is an attempt to create such repository of modules. I'm not talking about file format to describe the dependencies, but about the idea - you choose the dependencies, describe them in org.hibernate:hibernate-core:3.6.1.Final format and voila. What pisses me off is the variety of e.g. javax.xml.stream:stax-api artifacts - which one to choose? Which one doesn't contain f#$@ing javax.xml.namespace.QName class? Where are the sources? Where is javax.servlet:servlet-api:3.0 artifact which doesn't have glassfish or jboss in its groupId?

So the problem with Java is neither lack of modules, nor mechanisms for tracking/managing their dependencies, but the mess connected with artifacts related to standard JavaEE. Spring (or Hibernate) has clean modules, JavaEE - don't.

As for giant, no, I am of the view that the "actually useful bits" of SE and EE are quite a lot smaller than either platform ;-)

True, but there are so many to choose from - e.g. the aforementioned stax-api. Java (Ceylon) should not contain XML Parser (or HTTP Server, or CORBA, or even Swing!) All should come from libraries, not from rt.jar - if you want collections, take a library - I hope this is what you mean.

I want everyone to be able to publish their technology on a central, politically neutral, module repository where everyone can easily get at it.

I'm with you and I'm also advocate of such solution.

I would definitely like to set up some kind of independent group to steer the effort

I hope there will be no Collections.reverse(Arrays.asList(ELCARO.toCharArray())) in this group :)

No, that's JBoss 6 stuff. The new kernel of JBoss 7 (JBoss Modules) is significantly simplified.

I'll look at it. JBoss 6 isn't any better than JBoss 5.1 in that aspect...

regards Grzegorz Grzybek

 
15. Apr 2011, 13:51 CET | Link

I like the emphasis on readability, simplicity and short learning curve, all of which are painfully missing from Scala.

15. Apr 2011, 15:54 CET | Link
Daniel Serodio | dserodio(AT)gmail.com

What about Gosu? It seems to fix Java's annoyances without Scala's complexity.

 
15. Apr 2011, 16:44 CET | Link
oxbow_lakes

I think that Tony called your reply to Daniel dishonest because of your accusation that he was tweeting to the world that you don't know what you re talking about. As anyone who browses Daniel's twitter feed can attest, this was not the case.

 
16. Apr 2011, 06:31 CET | Link
JBoss User
Grzegorz Grzybek wrote on Apr 15, 2011 05:05:
No, that's JBoss 6 stuff. The new kernel of JBoss 7 (JBoss Modules) is significantly simplified. I'll look at it. JBoss 6 isn't any better than JBoss 5.1 in that aspect... regards Grzegorz Grzybek

See this http://in.relation.to/Bloggers/ModularizedJavaWithJBossModules for information on JBoss Modules. It's currently being used in JBoss AS7.

16. Apr 2011, 13:22 CET | Link
Grzegorz Grzybek | gr.grzybek(AT)gmail.com

@JBoss User, Gavin

See this http://in.relation.to/Bloggers/ModularizedJavaWithJBossModules for information on JBoss Modules. It's currently being used in JBoss AS7.

This looks great. No classpath - that's what I've been thinking of (https://github.com/grgrzybek/javaee-without-parent-classloaders/).

But I have simple analogy: if JavaSE is a runtime for plain classes/jars and JavaEE is a runtime for enterprise applications, then why JBoss people complain about bloated rt.jar (this is one of the principles of Ceylon - That's a job for libraries. We want to give you a choice: actors, STM, choose your poison.) which forces JavaSE applications to use standard library, when JavaEE does the same - App Servers are bloated and doesn't allow plain WARs to use their own e.g. apache-cxf-2.3.3.jar?

I hope Ceylon won't have endorsed standards mechanism and parent first classloaders... Classloaders aren't tools of evil, but the may be (and are) a pain if they force developers to use e.g. JAXP version from rt.jar. Java developers aren't idiots and they (usually) know what version of external libraries they want to use.

There is standard java repository of modules - Maven. Regardless of the format of pom.xml the idea is great - developers describe what artifacts their application depends on (e.g. org.hibernate:hibernate-core:3.5.6.Final) and that's all. The problem is with JavaEE - there are dozens of servlet-api JARs and nobody knows what's the difference betwenn stax-api-1.0.1 and stax-api-1.0_2. Also what is in your WEB-INF/lib isn't always what your WAR will use after deployment on JavaEE server (e.g. on WebSphere you'll use Axis2). So - Maven repository lacks only a good will of the deployers (especially those responsible for standard artifacts).

regards Grzegorz Grzybek

16. Apr 2011, 13:41 CET | Link
Grzegorz Grzybek | gr.grzybek(AT)gmail.com

@Gavin

One more thing about fundamental principles of Ceylon. I've been thinking about your arguments for creating/working on Ceylon:

  • Java is unashamedly focussed on problems relevant to business computing
  • Instead of modules, Java has multiple platforms, which has divided the developer community

But what is enterprise computing? For me it's

  • coding to interfaces and let the libraries/frameworks (generally: generic, reusable code) do the non-business stuff (transactions, audit, persistence, ...)
  • productivity - coding and keeping in mind, that the code will be 1000 more times read than (re)written), so productivity is often focusing on maintainability

So what JavaSE offers for me in enterprise area?

  • Eclipse - which allows me to be productive by using: CTRL+Space (with Lucene behind the scenes), ALT+SHIFT+Z, CTRL+ALT+arrowup/down, ALT+SHIFT+X T (with JUnit) and others
  • java.lang.reflect.Proxy - the heart of enterprise in JavaEE

And what are pain points of JavaSE/EE?

  • parent-first classloader which doesn't allow me to use the library I want without classloader hacks
  • JavaEE's APIs included in rt.jar (see above)
  • Application server's classloader's (see above)

And your words:

That's a job for libraries. We want to give you a choice: actors, STM, choose your poison.

What I want from Java? To keep away from staying between me and my application - I know what my application depends on, I know where the modules are (in Maven central), I just don't want endorsed mechanism and parent-first classloaders!

JavaEE's goal was to boost programmer's productivity by giving them APIs with implementation residing in application servers. But in practice the goal was to sell developers (managers) bloated app servers with vendor-lock-in option included.

I hope Ceylon won't have parent-firs classloaders... The syntax doesn't matter really.

regards Grzegorz Grzybek

 
16. Apr 2011, 14:23 CET | Link
I think that Tony called your reply to Daniel dishonest because of your accusation that he was tweeting to the world that you don't know what you re talking about. As anyone who browses Daniel's twitter feed can attest, this was not the case.

I'm sure Daniel is well-informed about many things, but one thing we know he is not well-informed on is Ceylon. Therefore it have been better if he had waited for a bit more information, no?

16. Apr 2011, 14:27 CET | Link
I hope Ceylon won't have "parent-first classloaders"

Classloaders are peers in JBoss Modules (I think that's the right terminology).

 
16. Apr 2011, 14:29 CET | Link

Dear Gavin King,

On behalf of Sri Lankan people and programming community I like to say thank you very much for selecting Ceylon as the name for the new language. We in Sri Lanka are excited to help and promote 'Ceylon' programming language. Just like Jakarta for Java, we are exited to see Colombo being the hub of open source projects for Ceylon.

Nalaka Gamage from Sri Lanka (Ceylon) www.nalakainfo.com

 
16. Apr 2011, 15:27 CET | Link

Jakarta - Apache for Java vs Colombo- Apache for Ceylon. Yes, it make lots of sense.

 
16. Apr 2011, 19:37 CET | Link
Charlie
Note that there are some overloading cases that can be handled by doing stuff like this:
void print<T>(T printable) 
        given T of String | Named {
    String string; 
    switch (printable) 
    case (is String) {
        string = printable;
    } 
    case (is Named) {
        string = printable.name; 
    }
    writeLine(string);
}
That code snippet is taken straight from the slides.

You can't be serious. To see instaceof() in Java code it's a fairly good sympthom of bad programming practices. I can accept that sometimes is's unavoidable, dealing when native/external code as COM libraries but.. as a substitute to overloading? Really?. To include support for a type based switch-case in a language, it's simply an awful idea.

As for the unanimous bad critics, you should take good note. To me Ceylon it's a better language than Java (not that it's difficult I must say), but not so much to overcome the cost of a language change, and learning a new API.

 
16. Apr 2011, 20:17 CET | Link
saeed
Lack of a language-level modularity solution resulted in the creation of monstrous, over-complex, harmful technologies like Maven and OSGi.

that' right , but Java 8 will come to address this issue by Java Module System as you know.

 
17. Apr 2011, 02:29 CET | Link
You can't be serious. To see instaceof() in Java code it's a fairly good sympthom of bad programming practices. I can accept that sometimes is's unavoidable, dealing when native/external code as COM libraries but.. as a substitute to overloading? Really?. To include support for a type based switch-case in a language, it's simply an awful idea.

First, that's not an instanceof, it's a completely typesafe construct that can never break (throw an exception) at runtime. The compiler validates that you've included all cases of the switched type. Remember that the reason why switching by type is considered harmful is that you might not remember to add a case to the switch when you add a new subtype of the switched type. But here the list of possible types is defined here in the method header as

String | Named
. Since the compiler forces us to handle both cases in the body of the method, there's no risk of the problem here. Remember, where not handling subtypes of some supertype in the switch. We're handling unrelated types.

Second, this is totally, 100%, exactly, precisely semantically equivalent to overloading, it cannot possibly be more harmful than overloading.

As for the unanimous bad critics, you should take good note. To me Ceylon it's a better language than Java (not that it's difficult I must say), but not so much to overcome the cost of a language change, and learning a new API.

Perhaps, perhaps not. Time will tell. Who can know the future?

 
17. Apr 2011, 02:36 CET | Link
As for the unanimous bad critics

P.S. The bad critics might be unanimously hostile, but on the other hand we've actually got a whole bunch of really good feedback from the more open-minded side of the community and especially from some of the older Java folks I respect. Most of the bad critics seem to be Scala fans upset that there might be some competition in the future. I honestly believe competition is a good thing for the community, and I'm looking forward to some interesting, gentlemanly discussions in the future. But first, we've got a compiler to write!

 
17. Apr 2011, 02:43 CET | Link
Lack of a language-level modularity solution resulted in the creation of monstrous, over-complex, harmful technologies like Maven and OSGi. that' right , but Java 8 will come to address this issue by Java Module System as you know.

Well, hopefully, and if they end up getting something reasonable done here in a reasonable timeframe, then we'll probably just reuse that work. If not, we already have something else we can use. We're wait-ing and see-ing.

Also, what I think of modularity is bigger than just what OSGi or JMS do. It needs to be built all the way back into the toolchain including the compiler. So something like JMS is not enough on its own.

 
17. Apr 2011, 02:49 CET | Link
I was hoping to get some clarity on the polymorphism of operator types. You stated in your slides that + is the equivalent of Numeric.plus()

Right.

If I understand this correctly, you're not just calling the method 'plus' but actually validating that the calling object is a Numeric before the operation takes place, and that the reason for this is to force the caller to satisfy Numeric so that you can prevent abuses of the operator being utilized in non-numeric contexts. Did I get that right?

Yes. We don't consider a method to be the addition operation just because it's called plus. It needs to be the plus() method of Numeric,

Are these operators implicit in the language or are they explicitly defined? If they aren't explicit then why?

They are explicitly enumerated in the language spec. You can't add your own &*-*@ operator.

 
17. Apr 2011, 04:11 CET | Link
Charlie
First, that's not an instanceof, it's a completely typesafe construct that can never break (throw an exception) at runtime. The compiler validates that you've included all cases of the switched type. Remember that the reason why switching by type is considered harmful is that you might not remember to add a case to the switch when you add a new subtype of the switched type. But here the list of possible types is defined here in the method header as
String | Named
. Since the compiler forces us to handle both cases in the body of the method, there's no risk of the problem here. Remember, where not handling subtypes of some supertype in the switch. We're handling unrelated types. Second, this is totally, 100%, exactly, precisely semantically equivalent to overloading, it cannot possibly be more harmful than overloading.

That's not the reason, as there are many. First, the same can be done via polymorphism, in a modular, extensible and maintainable way. Yeah, OK, there are corner cases, as I said, when you can justify the smelly instanceof, but, are there enough to include a specific construct and sacrifice overloading?. No. Second, semantically many things looks the same when we talk about programming. In this specific case, using a type-switch rather than overloading translates to a potentially huge method that will probably end calling a specialized method for each case. Overloading does it better. And this is an improved instanceof/typeid/typeof, no more, no less, you are checking the type at runtime.

Perhaps, perhaps not. Time will tell. Who can know the future?

It's true; it's just a guess to say it will not succeed at this point in time.

P.S. The bad critics might be unanimously hostile, but on the other hand we've actually got a whole bunch of really good feedback from the more open-minded side of the community and especially from some of the older Java folks I respect. Most of the bad critics seem to be Scala fans upset that there might be some competition in the future. I honestly believe competition is a good thing for the community, and I'm looking forward to some interesting, gentlemanly discussions in the future. But first, we've got a compiler to write!

It looks like you're in a really defensive stance: who comes the criticism from shouldn't matter, good or bad, but the reasoning behind it. Certainly, after all the polemic that has grown up in the Java community these days about Ceylon, at least some negative feedback must be well-grounded, isn't it?

 
17. Apr 2011, 05:58 CET | Link
First, the same can be done via polymorphism, in a modular, extensible and maintainable way.

On the contrary, it's quite clear that if you're thinking about using overloading to solve the problem, then for some reason you have decided you can not do it using polymorphism. Overloading is considered a (very impoverished) kind of polymorphism, bit when people counsel you to use polymorphism instead of a switch, they are definitely not suggesting that you use overloading to solve the problem!

Yeah, OK, there are corner cases, as I said, when you can justify the smelly instanceof

Actually, there are some quite reasonable cases. For example, problems where you would think of using the Visitor pattern can be expressed much less verbosely with a typesafe switch. Actually, the whole Visitor pattern is nothing more than an implementation of typesafe switch for languages that don't have it built in. If this isn't clear, consider the following:

abstract class Node() {
    shared formal void accept(Visitor v);
}
class Leaf(Object val) extends Node() {
    shared Object value = val;
    shared actual void accept(Visitor v) { 
        v.visitLeaf(this); 
    }
}
class Branch(Node left, Node right) extends Node() {
    shared Node leftChild = left;
    shared Node rightChild = right;
    shared actual void accept(Visitor v) { 
        v.visitBranch(this);
    }
}
interface Visitor {
    shared formal void visitLeaf(Leaf l);
    shared formal void visitBranch(Branch b);
}
void print(Node node) {
    object printVisitor satisfies Visitor {
        shared actual void visitLeaf(Leaf l) {
            writeLine("Found a leaf: " l.value "!");
        }
        shared actual void visitBranch(Branch b) {
            b.leftChild.accept(this);
            b.rightChild.accept(this);
        }
    }
    node.accept(printVisitor);
}

Here, the Vistor interface actually fills the role of encoding the enumerated list of subtypes of Node. If we add a new kind of Node, then every implementation of Visitor breaks, because we add a new formal method to Visitor.

Now, in Ceylon (and also in functional languages) we don't need the verbosity of the Visitor to achieve the same effect. Here's a prettymuch equivalent implementation in Ceylon:

abstract class Node() of Leaf | Branch {}
class Leaf(Object val) extends Node() {
    shared Object value = val;
}
class Branch(Node left, Node right) extends Node() {
    shared Node leftChild = left;
    shared Node rightChild = right;
}
void print(Node node) {
    switch (node)
    case (is Leaf) {
        writeLine("Found a leaf: " node.value "!");
    }
    case (is Branch) {
        print(node.leftChild);
        print(node.rightChild);
    }
}

That's a lot less code, right? And yet from a code maintainability perspective it is exactly equivalent. Addition of a new subtype of Node results in a compile error in print(), which is what we want.

Note: this stuff is well-understood in the FP community, but not yet in the whole OO community.

are there enough to include a specific construct and sacrifice overloading?.

There are, I think, really, really good reasons for not supporting overloading in a language with parametric polymorphism and type inference. I'm willing to bet you don't actually know all the compiler rules relating to overloading and generics in Java. That's OK, most Java developers don't. But I personally have a major problem with including language features that you know ahead of time that most developers will never completely understand.

In this specific case, using a type-switch rather than overloading translates to a potentially huge method that will probably end calling a specialized method for each case. Overloading does it better.

In my Visitor example above, the type case approach is much less verbose.

And this is an improved instanceof/typeid/typeof, no more, no less, you are checking the type at runtime.

Not true. It's quite different. We check at compile time that all subtypes are accounted for. That is simply not the case with instanceof.

It looks like you're in a really defensive stance: who comes the criticism from shouldn't matter, good or bad, but the reasoning behind it. Certainly, after all the polemic that has grown up in the Java community these days about Ceylon, at least some negative feedback must be well-grounded, isn't it?

Examples? Links? Honestly, I really haven't seen very many actual technical criticisms yet, as is to be expected, since all people have to go on is a few slides! There are indeed some design decisions that will be very controversial. For example:

  • removing overloading, especially constructor overloading,
  • removing support for final classes,
  • replacing public/protected/private with a single shared annotation.

These decisions remove capabilities that Java developers are used to. I think there's good reasoning behind each decision, and I think reducing complexity in these areas makes space for new features that are eventually more powerful. But inevitably some folks won't agree.

 
17. Apr 2011, 07:12 CET | Link
Randall

Breaking news: Tony Morris dislikes something and calls someone ignorant.

17. Apr 2011, 07:23 CET | Link
Andy Bornstein

You called him ignorant, that's the textbook definition of ad hominem.

17. Apr 2011, 15:07 CET | Link
Anthony

Nice - Start by bashing the haters and conclude with I hate the JVM. Who's the biggest hater?

 
17. Apr 2011, 15:17 CET | Link
Anthony
OK, so you don't like Scala. Could you elaborate on what was wrong with Groovy, Mirah (http://www.mirah.org/) -- made by the JRuby guys, and already functional -- or Gosu (http://gosu-lang.org/)?
 
17. Apr 2011, 16:33 CET | Link
tzman

What about built in support for annotation scanning and AOP; at least any easy way of defining aroundInvoke?

 
17. Apr 2011, 17:24 CET | Link

Gavin, would you describe Ceylon as a multi-paradigm language or as an object-oriented language with functional features? I realize the distinction is probably irrelevant to many, but I think your answer will be a comment on the overall language approach.

 
18. Apr 2011, 01:13 CET | Link
What about built in support for annotation scanning and AOP; at least any easy way of defining aroundInvoke?

Yeah, I already have a great idea for how to do this.

 
18. Apr 2011, 01:45 CET | Link
Gavin, would you describe Ceylon as a multi-paradigm language or as an object-oriented language with functional features? I realize the distinction is probably irrelevant to many, but I think your answer will be a comment on the overall language approach.

Um, I guess it is not really how I describe it. I don't personally see the inclusion of first-class/higher-order functions as making something a functional language. Remember, some of the very first OO languages (I'm thinking especially of Smalltalk) had closures and higher-order functions, and I see it as something of a historical accident that since Java did not, that OO came to be associated with not having this feature. I certainly think OO languages should have this feature (and have always thought that, given that I arrived at Java by way of Smalltalk). (Oh, but I have some doubts over the slightly different question of whether Java can really successfully add this feature now, after all the frameworks and libraries have already been written.)

Of course, there are several language features here that came originally from the FP community: parametric polymorphism, algebraic datatypes, type classes, and the treatment of null. However, it's an open question whether there's anything especially functional about these ideas, since they're just language features that make sense in any kind of statically typed language.

To me, for a language to be truly functional, it needs to emphasize immutability to an extend that Ceylon does not. Sure, Ceylon does encourage use of non-variable values, but they are certainly not second-class citizens in the way they are in true FP. The language should also optimize tail-call recursion, which is really quite difficult to do on the JVM.

There's also couple of other things that the FP community just love and that basically all functional languages support, that I'm simply not that keen on: pattern matching and tuples. I just don't think the benefits of these features would outweigh the disadvantages given the shape of the rest of the language. Without these features, Ceylon code will always look a bit different to typical, idiomatic code in a functional language.

Finally, it's actually the declarative programming support (annotations, UI/structured data support via named argument invocations, and the typesafe metamodel) that is much more characteristic of this language. That's the real differentiator.

 
18. Apr 2011, 02:29 CET | Link
Charlie
On the contrary, it's quite clear that if you're thinking about using overloading to solve the problem, then for some reason you have decided you can not do it using polymorphism. Overloading is considered a (very impoverished) kind of polymorphism, bit when people counsel you to use polymorphism instead of a switch, they are definitely not suggesting that you use overloading to solve the problem!

In theory polymorphism has nothing to do with with method overloading, neither in practice. The question is, when people use a runtime type-checking mechanism to do it, often the same can be done correctly with polymorphism. In the rest of the cases, as with a Visitor pattern, overloading does it better, see below. It's bad manners to ask a object about it's type :)

Actually, there are some quite reasonable cases. For example, problems where you would think of using the Visitor pattern can be expressed much less verbosely with a typesafe switch. Actually, the whole Visitor pattern is nothing more than an implementation of typesafe switch for languages that don't have it built in. If this isn't clear, consider the following:
abstract class Node() {
    shared formal void accept(Visitor v);
}
class Leaf(Object val) extends Node() {
    shared Object value = val;
    shared actual void accept(Visitor v) { 
        v.visitLeaf(this); 
    }
}
class Branch(Node left, Node right) extends Node() {
    shared Node leftChild = left;
    shared Node rightChild = right;
    shared actual void accept(Visitor v) { 
        v.visitBranch(this);
    }
}
interface Visitor {
    shared formal void visitLeaf(Leaf l);
    shared formal void visitBranch(Branch b);
}
void print(Node node) {
    object printVisitor satisfies Visitor {
        shared actual void visitLeaf(Leaf l) {
            writeLine("Found a leaf: " l.value "!");
        }
        shared actual void visitBranch(Branch b) {
            b.leftChild.accept(this);
            b.rightChild.accept(this);
        }
    }
    node.accept(printVisitor);
}
Here, the Vistor interface actually fills the role of encoding the enumerated list of subtypes of Node. If we add a new kind of Node, then every implementation of Visitor breaks, because we add a new formal method to Visitor. Now, in Ceylon (and also in functional languages) we don't need the verbosity of the Visitor to achieve the same effect. Here's a prettymuch equivalent implementation in Ceylon:
abstract class Node() of Leaf | Branch {}
class Leaf(Object val) extends Node() {
    shared Object value = val;
}
class Branch(Node left, Node right) extends Node() {
    shared Node leftChild = left;
    shared Node rightChild = right;
}
void print(Node node) {
    switch (node)
    case (is Leaf) {
        writeLine("Found a leaf: " node.value "!");
    }
    case (is Branch) {
        print(node.leftChild);
        print(node.rightChild);
    }
}
That's a lot less code, right? And yet from a code maintainability perspective it is exactly equivalent. Addition of a new subtype of Node results in a compile error in print(), which is what we want. Note: this stuff is well-understood in the FP community, but not yet in the whole OO community.

What you are doing here is mimicking functional pattern matching. The problem is, it looks like, but it isn't. There are some problems with Ceylon switch-type here (not different to scala pattern matching in this respect). You have forbidden to extend, as clients cannot add neither extend behaviour, they cannot modify the method, nor add new types (correct me if I am missing something here about Ceylon spec). Another problem is reusability, suppose you are doing something more or less elaborated while visiting, what are you going to do?, calling a method in each case?. If that's the case, what are you gaining here versus overloading?. And third, maintainability; your example has a trivial hierarchy but lets suppose you have a complex structure, with many node types and subtypes, you will end with a huge switch, growing and growing. And again to just call another method in each case. You even have a problem with reusing the code, as every bit you have done in every case statement is enclosed in the method containing the switch. Of course, this kind of pattern matching structure can be used if you don't expect the client to need to change it, or extend it, or reuse it (usually bad assumption), but in other cases, as with scala, you have an option. Use it, or take the overloading route. In your example, overloading will take some more LOCs(can be done shorter in other languages), but you can extend it, easily reuse the code and most importantly, keeping the code more modular in separate methods, help mantainers. I can see pattern matching usage in Scala or Erlang or F#, but hardly here, as the switch-type can be used in more harmful contexts.

There are, I think, really, really good reasons for not supporting overloading in a language with parametric polymorphism and type inference. I'm willing to bet you don't actually know all the compiler rules relating to overloading and generics in Java. That's OK, most Java developers don't. But I personally have a major problem with including language features that you know ahead of time that most developers will never completely understand.

You bet, you lose ;). Anyway, I'm not a Java developer. I have some Java years experience, but I'm in the C++ and C# camp. Having a pretty good knowledge of both, Java and C#, I can see how badly Java needs to evolve, or a replacement in the JVM, as Ceylon could be. On the contrary to you, I think developers must have choice. Many damn good developers don't know their languages at 100-percent, but middleware, framework and library developers can take advantage of some features less known. In fact this is the case in C++, there are some exceptional libraries as Boost, that exploit some dark language features and programming paradigms, like template meta-programming. Most programmers don't do it, but they benefit via libraries from them.

Not true. It's quite different. We check at compile time that all subtypes are accounted for. That is simply not the case with instanceof.

It's safer, I give you that one. In practice, you are manually cheking type at runtime with your code. My biggest concern with instanceof is not runtime exceptions, but the existence of (almost always) better alternatives, and the clumsy code structure it leads to. I have commented your example above.

Examples? Links? Honestly, I really haven't seen very many actual technical criticisms yet, as is to be expected, since all people have to go on is a few slides! There are indeed some design decisions that will be very controversial. For example:
  • removing overloading, especially constructor overloading,
  • removing support for final classes,
  • replacing public/protected/private with a single shared annotation.
These decisions remove capabilities that Java developers are used to. I think there's good reasoning behind each decision, and I think reducing complexity in these areas makes space for new features that are eventually more powerful. But inevitably some folks won't agree.

You have said you're taking into account some good feedback, from more open-minded folks. If there are only a few slides, not enough to do real technical criticism, how can it be enough to praise, but not to criticize? Haven't found any bit of truth in all those negative comments?

 
18. Apr 2011, 04:37 CET | Link
gerferra

oxbow-lakes said:

I think that Tony called your reply to Daniel dishonest because of your accusation that he was tweeting to the world that you don't know what you re talking about. As anyone who browses Daniel's twitter feed can attest, this was not the case.

and then you responded:

I'm sure Daniel is well-informed about many things, but one thing we know he is not well-informed on is Ceylon. Therefore it have been better if he had waited for a bit more information, no?

Are you saying that Daniel should have waited for a bit more information to say something he doesn't said?

 
18. Apr 2011, 05:31 CET | Link
On the contrary, it's quite clear that if you're thinking about using overloading to solve the problem, then for some reason you have decided you can not do it using polymorphism. Overloading is considered a (very impoverished) kind of polymorphism, bit when people counsel you to use polymorphism instead of a switch, they are definitely not suggesting that you use overloading to solve the problem!
In theory polymorphism has nothing to do with with method overloading, neither in practice.

Overloading (ad hoc polymorphism) is often considered a kind of polymorphism, along with generics (parametric polymorphism) and subtype polymorphism. (I suppose that Haskell type classes and ML modules represent some kind of fourth kind of polymorphism, though I'm not quite sure quite what to call it. It's related to subtype polymorphism, I suppose.)

The question is, when people use a runtime type-checking mechanism to do it, often the same can be done correctly with polymorphism. In the rest of the cases, as with a Visitor pattern, overloading does it better, see below. It's bad manners to ask a object about it's type :)

The point I'm making is that the argument made by OO folks for the use of polymorphism (by which we mean subtype polymorphism) instead of switching by type is a red herring here. I'm using switching by type instead of overloading (ad hoc polymorphism). Different circumstance. The arguments don't apply.

What you are doing here is mimicking functional pattern matching. The problem is, it looks like, but it isn't.

No, it's definitely not pattern matching, Ceylon doesn't feature pattern matching at all. It's a typesafe type switch. Very different. It's kinda related to how we handle null values with if (exists), and that's where I copied the idea from. It's almost like we've built support for the visitor pattern into the language if you prefer to think of it like that.

There are some problems with Ceylon switch-type here (not different to scala pattern matching in this respect). You have forbidden to extend, as clients cannot add neither extend behaviour, they cannot modify the method, nor add new types (correct me if I am missing something here about Ceylon spec).

But these exact same problems exist in the Visitor pattern or with ad hoc polymorphism. I'm really surprised that you still don't seem to get this point. Ad hoc polymorphism and the visitor pattern do not support extensibility like subtype polymorphism does.

Another problem is reusability, suppose you are doing something more or less elaborated while visiting, what are you going to do?, calling a method in each case?. If that's the case, what are you gaining here versus overloading?.

The benefits of typesafe switches vs. the visitor pattern are:

  • less code, and
  • the fact that the data structure being visited doesn't need to anticipate the needs of the code that is visiting it (which may be in a different module).
And third, maintainability; your example has a trivial hierarchy but lets suppose you have a complex structure, with many node types and subtypes, you will end with a huge switch, growing and growing.

Or a huge Visitor interface, growing and growing. Or a huge list of overloading methods with the same name. What's the difference?

In your example, overloading will take some more LOCs(can be done shorter in other languages), but you can extend it, easily reuse the code and most importantly, keeping the code more modular in separate methods, help mantainers.

On the contrary, overloading is no more modular, reusable, or extensible. That's why very many OO purists are quite hostile to it.

On the contrary to you, I think developers must have choice. Many damn good developers don't know their languages at 100-percent, but middleware, framework and library developers can take advantage of some features less known. In fact this is the case in C++, there are some exceptional libraries as Boost, that exploit some "dark" language features and programming paradigms, like template meta-programming. Most programmers don't do it, but they benefit via libraries from them.

I think languages like Haskell and ML demonstrate that you can have a very powerful type system without too much "dark"-ness. I agree that C++ does not demonstrate this ;-)

You have said you're taking into account some good feedback, from more open-minded folks. If there are only a few slides, not enough to do real technical criticism, how can it be enough to praise, but not to criticize? Haven't found any bit of truth in all those negative comments?

For the second time I request links, so I have some idea of which negative comments we're talking about here.

Honestly, your posts here are pretty much the only truly technical criticism I've seen. Are you unhappy with the manner in which I've responded? I feel like I've taken your arguments seriously and responded in a fair-minded way.

 
18. Apr 2011, 05:48 CET | Link
gerferra

Gavin,

As a Scala fan I'm a bit sad to see Red Hat creating a new language in opposition to support Scala. That's because, in my opinion, one of the big things that Scala is lacking for massive adoption it's a big enterprise supporting it.

From my point of view Red Hat supporting an in-house language for the JVM has its weaknesses. Any developer considering Ceylon will be worried about depending too much in the whims of one big enterprise. In this case this apply to the language/compiler and the purposed dependency to JBoss-modules.

Red Hat supporting Scala could be a win for the community, combining language independence and enterprise expertise.

I know that you don't like the syntax, but putting that aside, maybe there are options to get the features you want without creating a whole new language (and tools....).

For what I have read, much of the features you want are already present in Scala. Maybe it would be a much more beneficial effort for the community to invest in tools to limit some features of Scala based on profiles, and create a Ceylon profile which gives an error or warning every time one uses a feature outside the profile. This way you could guarantee that nobody in your team uses some feature considered unsafe or too hard.

Regards, Germán

 
18. Apr 2011, 14:57 CET | Link
As a Scala "fan" I'm a bit sad to see Red Hat creating a new language in opposition to support Scala. That's because, in my opinion, one of the big things that Scala is lacking for massive adoption it's a big enterprise supporting it.

I understand that the Scala community would like to see Red Hat get behind Scala, but I believe we have a responsibility to ourselves and our customers to do what we think is technically right. It would go against everything we stand for to go out there and start promoting a technology that we simply don't believe in.

From my point of view Red Hat supporting an in-house language for the JVM has its weaknesses. Any developer considering Ceylon will be worried about depending too much in the whims of one big enterprise. In this case this apply to the language/compiler and the purposed dependency to JBoss-modules.

I don't get this. Scala also has a commercial enterprise behind it. Are you saying you prefer technologies supported by small companies to technologies supported by large companies? What happens when the small company gets purchased by a larger company? Do you go looking for something else?

For what I have read, much of the features you want are already present in Scala.

We don't pick a language on the basis of how many features it has. If that were the criteria, someone could create an uber-language with all features of all other existing languages, and then everyone would be happy with this superset language and no-one would even need to create another language, because they could just add whatever features felt were missing to the uber-language. But no, on the contrary, a language needs to choose a small set of features that really work together and are sufficient to solve problems in the field it's targeted to, and then provide a beautiful, regular, consistent syntax to express those features. Folks are going to judge a language by how well the language features and libraries hang together, and by how cleanly the syntax expresses the language features.

 
18. Apr 2011, 15:30 CET | Link
tzman
The question is, when people use a runtime type-checking mechanism to do it, often the same can be done correctly with polymorphism. In the rest of the cases, as with a Visitor pattern, overloading does it better, see below. It's bad manners to ask a object about it's type :)
The point I'm making is that the argument made by OO folks for the use of polymorphism (by which we mean subtype polymorphism) instead of switching by type is a red herring here. I'm using switching by type instead of overloading (ad hoc polymorphism). Different circumstance. The arguments don't apply.

I believe thare are legitimate use cases for all of the approaches mentioned. I can see Gavin's point to the usefulness of a typesafe switch that provides an error when all subtypes are not accounted for explicitly. However, this does not cover all use cases and I do not think that is the intention. ad hoc polymorphism is also useful, I agree from a purist point of view using a static intializer or converter class is cleaner but in reality it is not always that simple. From a library point of view, you may not always know what the caller is going to have and providing overloaded methods just saves the caller from doing the work themselves and makes it easier for the caller to use the library. Using a different method name or a static converter class to do the same thing I see as a work araound. That being said, there is not near enough information available to decide whether the trade offs are worth it, but I am interested in enough to wait and find out. So, how long is the wait going to be?

 
18. Apr 2011, 15:32 CET | Link
g.o.

Gavin,

Maybe this is a bit out of focus, but I have some questions regarding data types and Ceylon as a general purpose language, including low level stuff:

Is there a plan for a fast and efficient way to read binary data into classes?

Just a question concerning the JVM: Since lack of unsigned data types seems to be a lack of the JVM, Ceylon will also not support unsigned data types, right? You mention primitive types as a frustrating part - I am a bit concerned about performance penalties w/o primitives...

Best regards, g.o.

 
18. Apr 2011, 20:54 CET | Link
ShawnP

Not to beat a dead horse here, but wanted to add my two cents.. Scala exists, and solves for most of the problems you are looking to with Ceylon. Why don't you help fulfil your own goals and support it's rising to be a viable replacement to Java instead of further fracturing the market?

 
18. Apr 2011, 21:49 CET | Link
LetsKeepFanningTheFlames
ShawnP wrote on Apr 18, 2011 14:54:
Not to beat a dead horse here, but wanted to add my two cents.. Scala exists, and solves for most of the problems you are looking to with Ceylon. Why don't you help fulfil your own goals and support it's rising to be a viable replacement to Java instead of further fracturing the market?

Not to beat a dead horse, but your question has already been answered by Gavin.

 
19. Apr 2011, 14:04 CET | Link

Indeed, all the syntactic stuff is nice, but proper support for unsigned types like .NET has would truely make a difference. Otherwise it's just java with another paint job.

 
19. Apr 2011, 14:34 CET | Link
Kondwani Mkandawire | kondwani(AT)gmail.com
Still going through the PDF slide, I'm not quite sure about the statement:

"resulted in the creation of monstrous, over-complex, harmful technologies like Maven and OSGi"

Could you please explain that statement, coz with all due respect that reeks of either arrogance
or lack of understanding of maven.

I currently am using Maven on a fairly large project - with Hibernate (thank you for that OS
contribution).

Back to the issue, to simply state something is a harmful technology without proper clarity and
justification rely sets up question marks. I see you have the sub-bullet:

"Instead of modules, Java has multiple platforms, which has divided the developer community"

This places no justification on the initial justification of Maven being a harmful
technology.
 
20. Apr 2011, 05:54 CET | Link

Hi Gavin,

Interesting when you said that ceylon never be a java replacement. So what exactly your / your team plan about this language? What the environment target? In what kind of condition developer should be choose between ceylon and java?

And one thing that I never understand is that, you create CDI specs, but instead of try to continue to make it better (and make other specs better), you decide to create whole another new language. My question is, in the future, if ceylon successfully adopted by community, do you have a high priority plan to support integration between Java (especially CDI) and Ceylon? Or CDI will be end up just like seam 2 (which no another killer features and IMO hard to integrate with new specs like Java EE 6)?

 
20. Apr 2011, 20:44 CET | Link
Denis Washington

At the end of the second part of the presentation (The Ceylon Type System), it says We need help implementing the compiler and designing the SDK. / This is a great time to make an impact! Does that mean that Ceylon will become a community-based project? Is there any way to help already?

 
20. Apr 2011, 22:51 CET | Link
John Lewis

In the less is better category, why have two assignment operators, one for variable values (:=) and one for immutable values (=)? I get why the variable attribute in the declaration is used, but once that is established, I don't see what having two assignment operators gets you.

 
21. Apr 2011, 16:53 CET | Link
Charlie
Overloading (ad hoc polymorphism) is often considered a kind of polymorphism, along with generics (parametric polymorphism) and subtype polymorphism. (I suppose that Haskell type classes and ML modules represent some kind of fourth kind of polymorphism, though I'm not quite sure quite what to call it. It's related to subtype polymorphism, I suppose.)

OK, we are entering here in a very academic discussion in this point. I really see it as a term abuse to call polymorphism to completely different features. And indeed overloading (ad hoc polymorphism) has nothing to do in practice with polymorphism (subtype polymorphism) and theoretically (conceptually if you like), again, overloading is a different feature. That's what I meant. So, I find completely logical the fact that the overwhelming majority of the literature in this respect use the term overloading.

What you are doing here is mimicking functional pattern matching. The problem is, it looks like, but it isn't. No, it's definitely not pattern matching, Ceylon doesn't feature pattern matching at all. It's a typesafe type switch. Very different. It's kinda related to how we handle null values with if (exists), and that's where I copied the idea from. It's almost like we've built support for the visitor pattern into the language if you prefer to think of it like that.

That's what I've said, it isn't :). But you are trying, or at least so it seems to me, to partly mimick pattern matching behaviour with it. You mentioned type-switching as somewhat alien to the whole OO community, but not so to the functional one, I understood because pattern matching existence in FP languages. Still, even if the feature is present mainly to implement the Visitor, I don't see it as an improvement over overloading, specially as it has many more use cases.

But these exact same problems exist in the Visitor pattern or with ad hoc polymorphism. I'm really surprised that you still don't seem to get this point. Ad hoc polymorphism and the visitor pattern do not support extensibility like subtype polymorphism does.

Not the same, although they share some problems. With a traditional Visitor implementation, I can, for example extend an existing class that implement the interface, or consume it's individual methods. But I can't do that with the type-switch variant. If anything I really prefer to have each case in one method rather than one huge method containing all that code, and again probably calling additional methods. In some languages you can even add methods to any class (like Ruby, although I don't ), so you can keep it open. I see your point, I hope you see mine.

Or a huge Visitor interface, growing and growing. Or a huge list of overloading methods with the same name. What's the difference?

It may be a matter of taste, but I see a clear advantage in having twenty 10-LOCs methods than one 200-LOCs method.

I think languages like Haskell and ML demonstrate that you can have a very powerful type system without too much "dark"-ness. I agree that C++ does not demonstrate this ;-)

I cannot disagree :)

Honestly, your posts here are pretty much the only truly technical criticism I've seen. Are you unhappy with the manner in which I've responded? I feel like I've taken your arguments seriously and responded in a fair-minded way.

No, not in the slightest. Much on the contrary, I see a healthy open minded predisposition to discuss.

I really hope Ceylon will succeed, as I see Scala too much complex to became a mainstream language within the JVM. Java is a simple and easy to learn language, no doubt any alternative cannot be above in complexity to get wide adoption.

 
22. Apr 2011, 10:22 CET | Link
And indeed overloading (ad hoc polymorphism) has nothing to do in practice with polymorphism (subtype polymorphism) and theoretically (conceptually if you like), again, overloading is a different feature. That's what I meant.

It was you who was arguing that prefer polymorphism to switches was an argument for supporting overloading. This was the only reason I got into a discussion about terminology and distinguishing between things that are sometimes called polymorphism. Personally I tend to have my own (not-necessarily-totally-self-consistent) internal private language for thinking about things, which is why I sometimes get into trouble when some of my private-terminology slips out into the public sphere and gets misinterpreted ;-)

So, I find completely logical the fact that the overwhelming majority of the literature in this respect use the term overloading.

FYI, the terminology I described above is what is used in the academic literature and by the FP community. Of course it's normal within the OO community that polymorphism means subtype polymorphism.

But you are trying, or at least so it seems to me, to partly mimick pattern matching behaviour with it.

Again, I really don't see how what I'm doing here has much to do with pattern matching. It's just a switch by type. Just like what you do with C union types or Java enums or whatever. In fact, one of the arguments for this language feature is that it's a simpler solution for some problems where Java forces you to introduce an enum. (I find it quite common to have a parallel set of classes where each class represents an enum value.) And that, indeed, typesafe enum support can be layered over this language feature, as demonstrated in the slides.

Sure, in functional languages you do very often pattern match by type when dealing with algebraic data types, but that's not what makes it pattern matching. It would be pattern matching if I was writing something like this:

//not legal Ceylon code:
void print(Node node) {
    switch (node)
    case (is Leaf(value)) {
        writeLine("Found a leaf: " value "!");
    }
    case (is Branch(left,right)) {
        print(left);
        print(right);
    }
}

Now, I don't find this code especially easier to read than the earlier version and it is more fragile (since adding atttributes to the model can break the switch).

With a traditional Visitor implementation, I can, for example extend an existing class that implement the interface, or consume it's individual methods. But I can't do that with the type-switch variant.

Oh c'mon, it's trivially easy to rewrite the code like this, and I think it still works out slightly less verbose than the traditional Visitor pattern:

abstract class Visitor() {
    shared void visit(Node node) {
        switch (node)
        case (is Leaf) {
            visitLeaf(node);
        }
        case (is Branch) {
            visitBranch(node);
        }
    }

    shared formal void visitBranch(Branch b);
    shared formal void visitLeaf(Leaf f);
}

void print(Node node) {
    object printVisitor extends Visitor() {
        shared actual void visitBranch(Branch b) {
            print(node.leftChild);
            print(node.rightChild);
        }
        shared actual void visitLeaf(Leaf f) {
            writeLine("Found a leaf: " node.value "!");
        }
    }
    printVisitor.visit();
}
If anything I really prefer to have each case in one method rather than one huge method containing all that code, and again probably calling additional methods.

On the contrary, I think the above code is demonstrably better and more maintainable, because it localizes knowledge of the Visitor in the Visitor hierarchy instead of smearing the information across both the Visitor and Node hierarchies. This is especially important if Node and Visitor are defined in different modules.

In some languages you can even add methods to any class (like Ruby, although I don't ), so you can keep it open.

My personal experience with Smalltalk's support for open classes was very negative. Extensions (extension methods, implicit type conversions, etc) are one thing. Open classes are problematic, I believe.

 
22. Apr 2011, 10:31 CET | Link
The question is, when people use a runtime type-checking mechanism to do it, often the same can be done correctly with polymorphism. In the rest of the cases, as with a Visitor pattern, overloading does it better, see below. It's bad manners to ask a object about it's type :)
The point I'm making is that the argument made by OO folks for the use of polymorphism (by which we mean subtype polymorphism) instead of switching by type is a red herring here. I'm using switching by type instead of overloading (ad hoc polymorphism). Different circumstance. The arguments don't apply.
I believe thare are legitimate use cases for all of the approaches mentioned. I can see Gavin's point to the usefulness of a typesafe switch that provides an error when all subtypes are not accounted for explicitly. However, this does not cover all use cases and I do not think that is the intention. ad hoc polymorphism is also useful, I agree from a purist point of view using a static intializer or converter class is cleaner but in reality it is not always that simple. From a library point of view, you may not always know what the caller is going to have and providing overloaded methods just saves the caller from doing the work themselves and makes it easier for the caller to use the library. Using a different method name or a static converter class to do the same thing I see as a work araound.

Sure. I want to emphasize that I like overloading and I think it's useful. I believe the same goes for the rest of the team. The arguments for not supporting overloading in this language are not arguments for not supporting it in some other language which, for example, doesn't feature parametric polymorphism or type inference. My argument is simply that supporting all three of these language features in one language is a recipe for problematic edge cases. Note that Scala, for example, does include support for all three, so apparently they're comfortable wrestling with the edge cases. So it's clearly a judgment call.

 
22. Apr 2011, 12:58 CET | Link
Charlie
It was you who was arguing that prefer polymorphism to switches was an argument for supporting overloading. This was the only reason I got into a discussion about terminology and distinguishing between things that are sometimes called polymorphism. Personally I tend to have my own (not-necessarily-totally-self-consistent) internal private language for thinking about things, which is why I sometimes get into trouble when some of my private-terminology slips out into the public sphere and gets misinterpreted ;-)

No need to argue more about this :)

Again, I really don't see how what I'm doing here has much to do with pattern matching. It's just a switch by type. Just like what you do with C union types or Java enums or whatever. In fact, one of the arguments for this language feature is that it's a simpler solution for some problems where Java forces you to introduce an enum. (I find it quite common to have a parallel set of classes where each class represents an enum value.) And that, indeed, typesafe enum support can be layered over this language feature, as demonstrated in the slides. Sure, in functional languages you do very often pattern match by type when dealing with algebraic data types, but that's not what makes it pattern matching. It would be pattern matching if I was writing something like this:
//not legal Ceylon code:
void print(Node node) {
    switch (node)
    case (is Leaf(value)) {
        writeLine("Found a leaf: " value "!");
    }
    case (is Branch(left,right)) {
        print(left);
        print(right);
    }
}
Now, I don't find this code especially easier to read than the earlier version and it is more fragile (since adding atttributes to the model can break the switch).

I only made that remark because I think pattern matching is the only language feature where you can do a switch by type (before Ceylon), and because you mentioned FP langagues in this respect. You can only do it in Java or C by value, not by type. It's a big difference. Even in C you do that as a hack, not as an intended mechanism. I'm surprised you don't find similarities between pattern matching and type-switch but you see a parallelism between switch-by-type and switch-by-value.

Oh c'mon, it's trivially easy to rewrite the code like this, and I think it still works out slightly less verbose than the traditional Visitor pattern:
abstract class Visitor() {
    shared void visit(Node node) {
        switch (node)
        case (is Leaf) {
            visitLeaf(node);
        }
        case (is Branch) {
            visitBranch(node);
        }
    }

    shared formal void visitBranch(Branch b);
    shared formal void visitLeaf(Leaf f);
}

void print(Node node) {
    object printVisitor extends Visitor() {
        shared actual void visitBranch(Branch b) {
            print(node.leftChild);
            print(node.rightChild);
        }
        shared actual void visitLeaf(Leaf f) {
            writeLine("Found a leaf: " node.value "!");
        }
    }
    printVisitor.visit();
}

That's what I've been saying. Using the type-switch you will end calling a different method in each case, because you need to, to keep the code maintainable.

On the contrary, I think the above code is demonstrably better and more maintainable, because it localizes knowledge of the Visitor in the Visitor hierarchy instead of smearing the information across both the Visitor and Node hierarchies. This is especially important if Node and Visitor are defined in different modules.

I think it's not :). Visitor interface must be defined within Node scope, and there you have all needed info. And you get far better IDE support navigating between methods than inside one.

My personal experience with Smalltalk's support for open classes was very negative. Extensions (extension methods, implicit type conversions, etc) are one thing. Open classes are problematic, I believe.

I agree. I haven't had professional experience working with Ruby or Smalltalk, but I can see getting into maintainability problems with large teams very easily. Many times looks like there is a legitimate use for them, mostly to add a few methods to the type when in other languages would end up as static utility methods. I find C# extension methods, although a different feature, a good and harmless substitute. You can add functionality to a closed type, without breaking encapsulation. Also you have a nice IDE support that mitigates biggest problem with traditional static utility methods, that is duplication, as it's difficult to keep all team aware of new functionality so you end having similar methods than mostly do the same. Inside Visual Studio, intellisense see them as class methods.

 
24. Apr 2011, 07:11 CET | Link
gerferra
I don't get this. Scala also has a commercial enterprise behind it. Are you saying you prefer technologies supported by small companies to technologies supported by large companies? What happens when the small company gets purchased by a larger company? Do you go looking for something else?

I was thinking about the licensing and that there will be some form of lock-in. Sorry, I was not clear. Now re-reading your post I see that you talk explicitly about making it a community effort, so I guess that the Ceylon compiler will be licenced with some free software licence (which is the case of Scala). Can you confirm this?

We don't pick a language on the basis of how many features it has. If that were the criteria, someone could create an uber-language with all features of all other existing languages, and then everyone would be happy with this superset language and no-one would even need to create another language, because they could just add whatever features felt were missing to the uber-language.

Understood.

But no, on the contrary, a language needs to choose a small set of features that really work together and are sufficient to solve problems in the field it's targeted to, and then provide a beautiful, regular, consistent syntax to express those features. Folks are going to judge a language by how well the language features and libraries hang together, and by how cleanly the syntax expresses the language features.

From my point of view Scala matches very much that definition. The problem is that what is considered sufficient changes with time. Once you have resolved the easy problems, you start to wonder how to better resolve the harder ones. I think Scala design is ahead in this regard, it's some steps above. I guess only time will tell.

The problem I see is that the Scala culture is somewhat different to the Java culture. It's in this regard that I think that maybe starting with a restricted, cleverly selected, set of features could easy the transition.

Thank you for your responses, sorry to bother in your blog.

Regargs, Germán

 
26. Apr 2011, 09:42 CET | Link
was thinking about the licensing and that there will be some form of lock-in. Sorry, I was not clear. Now re-reading your post I see that you talk explicitly about making it a community effort, so I guess that the Ceylon compiler will be licenced with some free software licence (which is the case of Scala). Can you confirm this?

Like all of our projects, it will be released under an open source license, probably GPL (+classpath exception).

From my point of view Scala matches very much that definition.

Obviously, it's somewhat subjective, and different people will come to different conclusions. I don't find Scala a very readable, visually consistent, or even a very regular language. And beauty tends to be a result of regularity and visual consistency. Hell, the grammar of Scala contains a whole subset of XML in it. To my way of thinking, that's gotta be about the irregularest and unbeautifulest thing you could do to a C-like language. But clearly some people like the idea. A second example is that the syntax for applying bounds to a type parameter is both cryptic and irregular compared to the syntax for defining subtype relationships in other kinds of type declarations. I'm just amazed that Scala actually managed to come up with something worse than Java's messy syntax for this stuff!

The problem is that what is considered "sufficient" changes with time. Once you have resolved the easy problems, you start to wonder how to better resolve the harder ones. I think Scala design is ahead in this regard, it's some steps above. I guess only time will tell.

Sure, most languages grow features over time, but my take on Scala is that it looks too me like it has grown too many features, much too quickly, without taking the time to really look at the potentially harmful unintended consequences of having simply so many features. And some of the more advanced features are accessed via extremely cryptic ascii-arty syntax that really hinders readability. But again, these are subjective judgments and people may disagree in good faith.

 
26. Apr 2011, 18:51 CET | Link
Ian
I hate to say it, but yeah, that's pretty much the case. As I'm sure you're aware, Java's syntax comes from C, which in turn draws heavily on Pascal and FORTRAN. Neither of these were designed to be 'mathematical' expressions. In fact, their formal origins are in providing a textual description of a Von Neumann machine. While this is clearly a mathematical structure, it's also a very complicated one and not the preferred model when dealing with computation from a theoretical perspective.

Wow - is it really lost on kids these days that FORTRAN originated specifically as FORmula TRANslation? They got tired of writing math/sci/eng code in Assembler, and FORTRAN is the result.

 
27. Apr 2011, 13:41 CET | Link
gerferra
Obviously, it's somewhat subjective, and different people will come to different conclusions. I don't find Scala a very readable, visually consistent, or even a very regular language. And beauty tends to be a result of regularity and visual consistency.

Absolutely agree that this and the others are subjective points. I think readability also has a lot to do with habituation to the syntax. Anyway, if I go back to the point where I started learning Scala I guess I had a better impression about readability with Scala than with Ceylon.

Hell, the grammar of Scala contains a whole subset of XML in it.

I believe this part is a bit unfair. Yes, you can write XML literals directly in Scala code, but from my point of view, this should be compared to write XML in Strings in other languages. Anyway I can't argue if having XML literals in the language is a good or bad thing, so if you think it is maybe it is. I've used them a couple of times and I liked it.

A second example is that the syntax for applying bounds to a type parameter is both cryptic and irregular compared to the syntax for defining subtype relationships in other kinds of type declarations. I'm just amazed that Scala actually managed to come up with something worse than Java's messy syntax for this stuff!

Apparently we have exactly opposite opinions regarding this :). I think type parameters are different things than classes or interfaces/traits, they are types in a more general form, and not conflate them with other constructs of the language helps to understand them. Also they occur in places where, from my point of view, it's better to have operators than long keywords to express they relations, it makes things more readable not less.

In general I found that the generics stuff in Scala is much more well-rounded than in Java. In my case I think that I actually understood Java generics after learning Scala generics, so worse it's not the word I would use.

Sure, most languages grow features over time, but my take on Scala is that it looks too me like it has grown too many features, much too quickly, without taking the time to really look at the potentially harmful unintended consequences of having simply so many features. And some of the more advanced features are accessed via extremely cryptic ascii-arty syntax that really hinders readability. But again, these are subjective judgments and people may disagree in good faith.

It's important to note that most of the features existed already in other languages and that the people involved in Scala development has a strong object-oriented and functional programming background. I think that there is an effort to not put too many things in the language, but to increase the power of the individual constructs and removing restrictions regarding the form in that you can combine them (obviously taking into account possible consequences regarding safety).

Don't know what cryptic ascii-arty syntax are you referring to. In Scala, methods can have non alphanumeric characters and, because of this, you don't have a difference between operators and methods, there are just methods. Maybe you are referring to methods in the standard lib?.

Regards, Germán

 
27. Apr 2011, 16:51 CET | Link
Absolutely agree that this and the others are subjective points. I think readability also has a lot to do with habituation to the syntax.

It's somewhat subjective. I don't think anyone can in good faith argue that Perl or Scala are as readable as Python. Not with any amount of habituation.

I guess I had a better impression about readability with Scala than with Ceylon.

Each to his own :-)

I believe this part is a bit unfair. Yes, you can write XML literals directly in Scala code, but from my point of view, this should be compared to write XML in Strings in other languages.

I never write XML strings in Java code. And no, importing half the grammar of XML into the grammar of the general-purpose language is not in any way comparable to the fact that you can embed an arbitrary language in a String literal. Not even remotely comparable.

I've used them a couple of times and I liked it.

Each to his own :-)

Apparently we have exactly opposite opinions regarding this :). I think type parameters are different things than classes or interfaces/traits, they are types in a more general form, and not conflate them with other constructs of the language helps to understand them.

I'm not sure if it's even worth the bother arguing against this. I think it's just so clear that a regular syntax for types in a more general form is exactly the kind of thing that good language design should aspire too. One of the highest principles in the design of Ceylon has been syntactic (and semantic) regularity.

Also they occur in places where, from my point of view, it's better to have operators than long keywords to express they relations, it makes things more readable not less.

It's perhaps better in Java and Scala where the type constraints occur inside the <...>. That's what you mean by occur in places. But if you drop this dumb syntax and follow the approach of C# and Ceylon, you won't anymore have the desire to avoid keywords.

And if you don't think there's a readability problem with >: instead of implements, then why not use it for specifying the implemented interfaces of a class? At least be consistent for chrissakes!

In general I found that the "generics stuff" in Scala is much more well-rounded than in Java

Scala does have overall a nicer generic type system than Java. But the syntax for type constraints is a definite wart.

It's important to note that most of the features existed already in other languages

I seem to keep needing to labor the point that just because a feature makes sense in language A, doesn't mean it makes sense in language B, especially when language B already has many features from languages C, D, and E. What matters is how well all the features hang together, not whether they are individually well-defined.

Don't know what "cryptic ascii-arty syntax" are you referring to.

Oh c'mon, don't be dense. I understand that the Scala community is in deep denial about this, and tends to respond with insults everytime someone mentions the problem, but you seem a bit more open-minded than that. The ratio of ascii characters to English words in Scala code is well above the average for successful languages. We've already talked about type constraints. Another example is + and - for (co|contra)variance. Another is the overabuse of operator overloading. I could go on.

 
27. Apr 2011, 19:43 CET | Link

Gavin, forget the haters. This Ceylon project looks perfect to me so far...actually made me want to start coding again. I've found no joy in the spate of languages ( ruby, etc) and look forward to a worthy successor to Java, by people who really appreciate that language.

 
27. Apr 2011, 23:42 CET | Link
I have used Groovy, Java and Python a lot. I also seriously looked into Scala and kicked the tires of Gosu. I have come to many of same conclusion that you have about type safety and language simplicity.

I think you are on the right path with Ceylon. Java jumped the shark a long time ago. Scala will only every have a small following. Scala syntax is too complex and butt ugly.

Ceylon is the right syntax at the right time (I think).

The Scala community reminds me of the Ruby community a few years back. Rabid but small (full of true believers). From reading your blog, it seems like you are being attacked by every rabid Scala fan out there (all 12 of them).

Keep up the good work. Ceylon looks great. I know I will start using it as soon as it is available.

Don't be discouraged. Ceylon appeals to the silent majority.

I for one, will be using it as soon as I can.
 
28. Apr 2011, 01:56 CET | Link
gerferra
It's somewhat subjective. I don't think anyone can in good faith argue that Perl or Scala are as readable as Python. Not with any amount of "habituation".

Ok, somewhat subjetive :).

And if you don't think there's a readability problem with >: (*) instead of implements, then why not use it for specifying the implemented interfaces of a class? At least be consistent for chrissakes!

(*) I guess you are referring to <:

I don't know, maybe Odersky et al. think that extends and with where better but too long to use to express type parameters bounds, so they used an operator instead in such cases. Given that I don't treat (mentally) type parameters and classes/interfaces in the same way, I don't feel and inconsistency. Maybe with Ceylon I won't have to treat them different, that would be a good thing.

Oh c'mon, don't be dense.

:), sorry. Maybe some of the denseness have to do with the difficulty I have expressing myself in English.

The ratio of ascii characters to English words in Scala code is well above the average for successful languages.

I guess I give a stronger meaning to cryptic ascii-arty syntax than you. I kind of like The ratio of ascii characters to English words in Scala code is well above the average for successful languages ;) but I think that cryptic ascii-arty syntax it's too strong.

I can't argue if a language cannot be successful if it have more operators than C / C++ / Java / C#.

 
28. Apr 2011, 06:15 CET | Link
(*) I guess you are referring to <:

Probably. Because I don't write Scala code every day, I can't keep in my mind which of <: and >: is an upper bound and which is a lower bound. I would have though that the arrow should point to the most abstract type like in UML, but maybe not. The equivalent keywords in Ceylon are satisfies (lower bound) and abstracts (upper bound), which are not really confusable.

Maybe with Ceylon I won't have to treat them different, that would be a good thing.

Right, we went to a lot of effort to make a type parameter look and feel and act like any other type.

 
30. Apr 2011, 13:45 CET | Link
gerferra
Probably. Because I don't write Scala code every day, I can't keep in my mind which of <: and >: is an upper bound and which is a lower bound. I would have though that the arrow should point to the most abstract type like in UML, but maybe not. The equivalent keywords in Ceylon are satisfies (lower bound) and abstracts (upper bound), which are not really confusable.

<: is a common symbol to refer to the subtyping relation, S <: T means S is a subtype of T.

 
30. Apr 2011, 15:32 CET | Link
<: is a common symbol to refer to the subtyping relation, S <: T means "S is a subtype of T".

Yeah, sure, you're right, <: is what they use in the academic papers. But then >: for lower bounds? Is that one in common usage? Shouldn't it be :>? And then you've got <% for view bounds. And then you've also got extends and with.

I mean, the above probably wouldn't be that bad, except that then you've also got the totally pervasive use operator overloading, and + and - for variance (which is which, again?), and arguable overuse of =>, and ... eventually my eyes just glaze over.

 
30. Apr 2011, 19:04 CET | Link
gerferra
But then >: for lower bounds?

Yes.

Is that one in common usage? Shouldn't it be :>?

Don't know, apparently it's not, also don't know why :> wasn't choosed.

So, we have S <: T == S satisfies T and S >: T == S abstracts T.

It's possible that you confused (the unconfusable) satisfies (upper bound) and abstracts (lower bound) in a prior response? :) (Just a joke to compensate the fact I couldn't respond why Scala uses >: and not :>.)

 
30. Apr 2011, 21:35 CET | Link
gerferra wrote on Apr 30, 2011 13:04:
It's possible that you confused (the unconfusable) satisfies (upper bound) and abstracts (lower bound) in a prior response? :) (Just a joke to compensate the fact I couldn't respond why Scala uses >: and not :>.)

Haha, yes, I did. Actually I wasn't confused about satisfies vs. abstracts - I know what they mean - but rather lower vs. upper bound. For some dumb reason my brain seems to pick upper|lower at total random when I'm not careful. :-)

 
14. May 2011, 18:14 CET | Link

Nice, clean syntax that I can see so far! But I wonder about java interoperability with the String? foo = ... syntax. Would you have to declare everything coming in from java as an Optional<T>?

Also, what would be the process for joining the library design/implementation ?

 
15. May 2011, 16:18 CET | Link
Michael wrote on May 14, 2011 12:14:
Nice, clean syntax that I can see so far! But I wonder about java interoperability with the String? foo = ... syntax. Would you have to declare everything coming in from java as an Optional<T>?

No, my take on this is that in Java we simply don't know if something is nullable or not - I think it's more correct to say that Java doesn't have typesafe nulls than to say that everything is supposed to be potentially null. On that basis, we will let you write either

String name = person.getName();

or

String? name = person.getName():

When you're calling a Java type. (Actually I'm inclined to let you write String name = person.name; in the case of calling a getter.)

If you write the first form, and getName() happens to return null at runtime, then an exception will immediately occur, because the compiler will wrap the call to getName() in a runtime null check.

The philosophy here is that we accept that NPEs can occur when calling Java code, since that's the nature of Java. But once you cross the boundary into Ceylon code, NPEs are no longer possible.

Also, what would be the process for joining the library design/implementation ?

We're not quite ready to start working on libraries yet (only the language module). Current work is all on the compiler. But send me an email so I can keep you up to date.

 
17. May 2011, 18:18 CET | Link
Gavin, I would like to see a more thorough comparison of Ceylon and Groovy++ (not Groovy)
I think, they are not so dissimilar.

I like that Ceylon has stayed away from the featuritis of Groovy and Scala,
while at the same time it has the courage to change things that are really broken - namely generics.

In everyday work, Ceylon should provide 99% of Scala's features, while reducing confusion by an order of magnitude.
This minimalism is much more in the original spirit of Java.

Of course there is one favourite feature, that I am missing: It is Groovy's convention that inline function definitions with one parameter do not need to declare it when using the default name "it".
This is a massive gain in ease of use and elegance, without creating a lot of complexity.
 
22. May 2011, 13:12 CET | Link
Suminda

This would be a opportunity to bring in Aspect Oriented, Composite Oriented features and Language Extensions and modifications. Operator overloading is very much missed in Java. A concise way to to this would be welcome. Also language level concurrency and self healing features would be welcome. Also ability to make a class immutable even when they are taken from other JVM languages. Also easy mixing JVM languages would be a winning factor. Another feature can be multiple inheritance with a twist i.e. the class can multiple type inheritance but the objects will be aggregated into the class. If the particular type is called then the relevant objects function is called but if there is a conflict or of the use want to do validation user must specify which function the call is delegated to. This is need the ability to strip a type to its interface as a set of delegates / closure. Also union intersection and minus to create new types of interfaces to which mapping closures and be attached would be interesting. Also other tools for dynamic type creation and delegation.

I am just shooting ideas. Let me know your thoughts.

 
02. Jun 2011, 15:31 CET | Link

The only thing I miss from the Celyon is method overloading. I'm really looking forward to see a working Celyon compiler and real use of Ceylon. I don't know if I'll start using Ceylon, but I see some very good ideas in the proposal and wish these would been incorporated into other languages someday.

All the best!

 
08. Jul 2011, 12:08 CET | Link
Xan
What are your thoughts about Fantom language? What are the differences and similarities with Ceylon?
And simple question: why this name? What this name means? I not found in slides.

Thanks,
Xan.
 
19. Aug 2011, 01:34 CET | Link

I am working on project that contains a lot of maths stuff with graphs, maths sets, intervals, unions, intersections and cetera.  Ceylon examples of Comparable,  graph and operators overloading are very impressive. I was not able to achieve clear design of my libraries, because of Java restrictions. Obviously, Ceylon code of my project should be much better.  So, I have some related to maths questions.  

  1. How do you estimate performance of Ceylon in compare to Java? I think it should be rather equal.
  2. How do yo handle boxing and unboxing? I mean int and Integer difference.
  3. In one of the post you mentioned powerful Ceylon Collections library. Would you be able to provide short description.
  4. Do you design collection library with Google Guava, GNU Trove and fastutil in mind?
23. Apr 2012, 12:12 CET | Link
Doug

No Braces!!! Completely redundant and arcane. I have programmed in Java and Cpluplus for 15 years but still hate those curly things.

Why are they needed when I indent every sub statement to a different level as well. On a team of developers, one of the biggest stylistic divides is between those who put the first brace on a new line and those who don't. This is not an issue in Python and probably one of the reasons it looks so much cleaner than Java.

 
18. Nov 2013, 10:59 CET | Link

Quote: I guess I just really don't feel that the whole language really hangs together the way Smalltalk or Haskell hang together.

Yes, that's also what I thought when looking at Scala: It is missing coherence. Putting the features of 10 languages alltogether into an 11th language is not all there is to it. How all those features form a new coherent language is the work a language designer has to think about. In my impression Scala falls short in this regard.

Post Comment