But I like Ceylon more because:
* Union and intersection types.
* I find the type system cleaner and more elegant.
* It's an attempt to build a whole new platform with a new SDK. Kotlin is, in a way, just a syntax skin over the Java platform.
* Reified generics. Kotlin got rid of them.
* I personally find Ceylon's "String str" more readable than Kotlin's "str: String".
* Type-safe metaprogramming.
* Comprehensions (not 100% sure Kotlin doesn't have them).
* It's compilable to JS.
* Slightly more regular syntax, more readable generic declarations, better web documentation, currying, spread operator, etc.
Thing is, neither Kotlin nor Ceylon (nor Scala, IMO) add something fundamentally necessary over what's available in Java (8). They mostly provide productivity enhancements. For me, added productivity is really nice, but it doesn't justify switching a language, unless it's a 10x productivity boost (Clojure is different; it provides a whole new way of thinking and managing state and data, which is very important for concurrency - this is big). So in that case, I'd rather give Java a facelift than change to something else altogether. Kotlin is just a Java facelift. It's trivial and transparent to mix Kotlin and Java classes, even in the same package.
I don't understand the Clojure bit - do you mean STM?
As for Clojure, I mean this: http://www.infoq.com/presentations/Value-Identity-State-Rich... (basically: immutability, controlled state transitions via agents/atomic/STM)
_Please_ try Ceylon IDE, and let us know where it's nonasskicking. We've worked very, very hard on it, and we think we have something really useful and usable, but of course we very much welcome feedback.
FTR, I personally pushed almost 240 klocs to this project over the past two years.
* Imperative programming is more straightforward in Ceylon.
* The same holds for functions with side-effects.
* Type safety is similar, Ceylon currently doesn't have type classes and generalized algebraic data types but will be probably added according to the FAQ.
* Ceylon is less type-inferred, which makes it more readable IMHO (1. regular syntax 2. type annotations are not just for the compiler, but for documentation too). Also - less confusing compiler errors.
* In general, Ceylon feels pragmatic, Haskell academic.
Except Haskell is being used in the industry already, while Ceylon is a Java wannabe replacement.
Just about every haskell program I write has functions with side-effects.
> * Ceylon is less type-inferred, which makes it more readable IMHO ... 2. type annotations are not just for the compiler, but for documentation too).
So having to write type annotations all the time is an advantage for you? You can just as easily add type annotations to Haskell, are you saying that since it is compiler enforced with Ceylon, that Ceylon code as a whole is easier to read?
Furthermore, doesn't less type-inferred just mean "type inference isn't as good", or was that a design decision?
> Also - less confusing compiler errors.
Any examples of confusing Haskell compiler errors? I personally haven't seen any memorably confusing compiler errors from Haskell. Have you seen any with Haskell or is that just something you've heard about?
Any examples of compiler errors where Ceylon beats Haskell? Any examples of compiler errors where Ceylon beats Java?
> 1. regular syntax
By "regular syntax" do you mean "algol derived or inspired"?
> * In general, Ceylon feels pragmatic, Haskell academic.
This is interesting, because it's something I've heard from just about everyone I've asked about Haskell. Recently I have delved into Haskell myself and haven't found it true.
For instance, arrows are something many consider "academic", but they enable the very pragmatic and real world advantage of handling HTML like:
-- haskell
-- added bonus of type safety through type inference!
images tree = tree >>> css "img" >>> getAttrValue "src"
-- python
def images(tree):
imgs = [elem for elem in tree if elem.tag == "img"]
sources = [img.get('src') for img in imgs]
return sources
-- alternate python
def images(tree):
return [ img.get('src' for img in filter(lambda i: i.tag == "img", tree)]
If my understanding is correct the Haskell above is (at least could) take advantage of stream fusion which has the real world advantage of being really efficient and really fast.> * In general, Ceylon feels pragmatic, Haskell academic.
This is something that is entirely subjective. I will have to look into Ceylon more in the future. I will say that from the outside Haskell looked very academic for me, but after writing some code, Haskell feels/seems to be/has proven to be a very pragmatic language that doesn't deserve a reputation of being "academic".
As a whole I wish that many other languages weren't just dismissed as "academic" so that we could innovate more quickly and improve technology as a whole. There are valid arguments to be had about much of the experimental stuff, but calling something "academic" is usually a cop out in my experience.
That's because just about every program needs side-effects. My point was that side-effects are more straightforward in Ceylon, you don't need monads.
> So having to write type annotations all the time is an advantage for you? You can just as easily add type annotations to Haskell, are you saying that since it is compiler enforced with Ceylon, that Ceylon code as a whole is easier to read?
Yes. I think that it makes the language more regular and less messy. When you look at foreign code, you can always immediately see the types. But I have little experience with Haskell or Scala, so I may be wrong.
> Furthermore, doesn't less type-inferred just mean "type inference isn't as good", or was that a design decision?
My guess is that it was a design decision. I think they wanted to have a interface model that's understandable and predictable (you can easily say whether type annottions are necessary or not).
> Any examples of confusing Haskell compiler errors? I personally haven't seen any memorably confusing compiler errors from Haskell. Have you seen any with Haskell or is that just something you've heard about?
No, I admit that this was something I read on Ceylon's site (I think) and it's quite possible I'm wrong here.
> By "regular syntax" do you mean "algol derived or inspired"?
Not sure how to put my intuitive understanding of "regular" into words... I would say that it means that the code has relatively few visual patterns, there's lower visual variance. It's like with tidy (= regular) vs messy (= irregular) rooms. It's easier to "understand" tidy room.
> This is interesting, because it's something I've heard from just about everyone I've asked about Haskell. Recently I have delved into Haskell myself and haven't found it true.
For me it's evident that Ceylon has very pragmatic focus on real-world productivity. I was excited about the design decesions and trade-offs they've made, I've often thought "yes, exactly my thoughts!" when reading the language design FAQ. On the other hand, I simply don't see the focus on productivity in Haskell. Do monads really increase productivity? Would a team of Haskell programmers implement a stackoverflow.com copy faster than, let's say, a team of similarly intelligent and experienced C# programmers?
> For instance, arrows are something many consider "academic", but they enable the very pragmatic and real world advantage of handling HTML like:
The Python code could be:
def images(tree):
return [img.get('src') for elem in tree if elem.tag == "img"]
It's almost as succint but seems more regular to me, it's just the old good comprehension, nothing fancy.> No, I admit that this was something I read on Ceylon's site (I think) and it's quite possible I'm wrong here.
FTR, I think you might have got mixed up here. Definitely good error reporting is a very major priority for the language, and I think we generally do better than Java at least when generics are involved, but we've never made any comparisons positive or negative to Haskell.
Well, there are very interesting tradeoffs here. If you want to go the "whole hog", i.e. HM type inference, where you don't need to annotate the types of parameters, you can't have subtyping (at least not in the usual sense yes yes I know about OCaml which requires an explicit upcast).
Now, I personally think subtyping is great, and it's even greater when you introduce first-class union+intersection types into the mix. So there's definitely a place for languages without full HM type inference.
Next, you could still have a system with more type inference than what Ceylon supports, but you would need an arbitrary number of passes over the code to infer types, and you would introduce the possibility of typing errors which can't be pinned down to a single erroneous expression.
So Ceylon supports a more limited sort of type inference: local type inference. The Ceylon compiler can infer and check all expressions in a single pass over the code, and every typing error is localized to a single expression.
And y'know what: that turns out to be a pretty reasonable thing practically speaking, since documenting the types of exported APIs is frankly a good thing to do anyway, and helps the people who come along later and look at your code.