Hacker Newsnew | past | comments | ask | show | jobs | submit | gavinking's commentslogin

Yay!

Folks, please feel welcome to Ask Me Anything.


Yay!

The language module is a 1.5MB JavaScript beast and people routinely complain about 150KB frameworks on HN. Are there plans to have a whole program optimisation pass to prune dead parts of that module (a ceylon webpack or ceylon closure command) ?


It seems to me that the best solution here is to split the single file into one js file for each package. A big part of that file is the implementation of the metamodel, and it's very likely that a lot of people won't even want to use that on the client side.

We've even discussed the pros and cons of actually splitting the metamodel into its own separate module, ceylon.metamodel, or whatever.

P.S. My tests with uglify-js suggest that minification probably isn't the most fruitful path here.


Once minified and gzipped it's less than 200K. But yeah, I can see how a packing command would be useful with program analysis, except that'd rule out any use of the metamodel for dynamic programming.


It's just a getter. Lots of languages have getters.


Ah that makes sense, thanks. I missed the implicit "we're in a class definition" in the original post.


So, that's a good example: ceylon.time is implemented in pure Ceylon, and is totally cross-platform.


Well where there is a big difference between the underlying capabilities of the platform, differences are unavoidable.

I mean, examples of things that are cross-platform in Ceylon: collections, localization, promises, regexes, HTML construction, logging, testing, dates/times.

Examples of things that are platform specific: I/O, database access, filesystem access, distributed transactions, the HTTP server.

That's pretty reasonable and natural, isn't it?


The date/time cross-platformness is a big deal for business-type applications, at the very least. You tend to transfer/use a lot of dates/timestamps/what-have-you in that type of application. (This is a constant source of pain for me in scala.js.)


ceylon.locale is also shaping up to be really useful. Localization in JS is just terrible.


Yes, that's another of my pet peeves with scala.js since it basically splits your world into two around formatting of dates/time/currency/etc. (Things may have changed recently, but it was sorely lacking up until a few months ago.)


Would you please open an issue here with the things you would like changed:

https://github.com/ceylon/ceylon-lang.org/issues

Thanks.


Well the thing is that Ceylon offers fantastically smooth interop with both Java and JavaScript. That's one of it's main selling features for most people.


Right, but by "interop" I didn't just mean the ability to call into Java code and vice-versa, although I admit that's the traditional definition. Scala can do that too.

What I meant is, Kotlin raised the bar in the interop department to new heights: it uses the same collection types, so there's no conversion between Java and some other SDK, but still manages to enhance them via compiler magic and extensions. It has an auto-converter tool so nobody has to waste time rewriting code that already works in order to use the new features. It can use annotation processors, etc.

Of course it also pays a fairly steep price to get that.


> but still manages to enhance them via compiler magic and extensions

The thing is that Scala tried to do that for years, and after years of battling subtle, leaky abstractions, they picked a different design.

It feels like Kotlin designers are completely unaware of what other languages tried and keep repeating all the mistakes ...


Hardly. The Kotlin designers specifically call out Scala's mistakes when discussing why they do things differently.

In my experience it works well. I've yet to encounter anything surprising or leaky. Actually the abstractions it provides are fairly thin: you can normally look at Kotlin code and understand quickly what it compiles down to.

It may be that in the end, Kotlin succeeds where Scala struggled, simply because the Kotlin designers do a better job.


Well, I don't think what you say is based on reality if you look at all the broken, half-designed stuff they are trying to ship. (Not understanding (yet) why some design decisions are bad, doesn't mean they aren't bad.)

It feels like they are digging through Scala's graveyard of discarded ideas without even realizing it. Most of what they try to do differently has already been considered in the past and has been rejected by the Scala developers for good reasons – years ago.

Kotlin's struggles are a good example that knowing how to build IDE support for existing languages doesn't give you the skills to design a programming language from scratch.

    The Kotlin designers specifically call out Scala's
    mistakes when discussing why they do things differently.
Yes, I have to give them that. They (and their "fans") excel at PR, marketing and FUD.


Different languages have different design tradeoffs. I had many profitable exchanges with Andrey Breslav and other Kotlin designers. We can have a technical discussion about the design choices without getting into a fight about who is more competent.


Could you please give a few examples of "all the broken, half-designed stuff they are trying to ship"?


- extension methods

- property syntax + magic identifier

- reified

- immutable wrappers around mutable collections

- const

- multiple redundant ways of defining generic upper bounds

- companion objects + syntax

- operator/infix rules

- constantly changing nullability rules


I think you are falling into the mistake of associating what you call design with features. How features are implemented and how consistent they are with some pure notion of their role is secondary to how they serve the high-level design goals. Once you understand Kotlin's design goals you see that the features and their implementation make a lot of sense. If you think the features aim to serve another goal, then the features might seem inconsistent. Outside of academic languages, language features exist to serve particular purpose, and so their "academic" form may be compromised to serve that purpose better. There is no point in isolating features from their purpose and then arguing over them without first understanding their goal in that particular language, as the same feature can serve different (or subtly different) purposes in different languages, or a feature must be twisted in order to allow the goal to be better achieved. There is no way to say whether a feature is good or "broken" without first analyzing the language's goals, and a feature that may be bad in one language may be great in another.

As Scala (or Ceylon) has such radically different goals from Kotlin, it doesn't make much sense to discuss which features were imported and how without first understanding the why. Kotlin's designers didn't say, "I like this Scala feature but not that one"; they said, "we have this goal and this Scala feature serves it but that one doesn't". A language is not measured by what features it has, but by how those features serve its goals, and whether those goals are appropriate to begin with (i.e. provide a good cost/benefit ratio).


Sorry, but I don't plan on reading your confused ramblings.


Have I done something to offend you? Because you are being extremely rude. You are entitled to think whatever you want about my ramblings, confused or otherwise, and you are even entitled to not try to understand them or even read them at all. But your outbursts are inappropriate. Continue expressing yourself in this way and you will be banned from HN.


What's broken about extension methods? I have zero experience Scala and about a week's worth of experience with Kotlin, but so far I'm finding extension methods to be pretty straightforward and useful. What am I missing?


Extremely poor cost/benefit ratio.


Extremely poor cost/benefit ratio for what purpose? If your main goal is to adopt existing classes and libraries as your own (i.e. without any loss of functionality compared to language-native libraries), then extension methods obviously have an extremely high cost/benefit ratio. You can't analyze a feature in isolation of the language's goals. Features exist to serve a purpose, and are measured by how well they serve it.


To give an analogy, a shoulder-fired missile might have a terrible cost/benefit ratio if you're trying to hunt an antelope, but if you're trying to disable a tank, then I'd say it's cost/benefit ratio is pretty good.


Well, y'know, you could go with your gut - or you could actually try it out for yourself!

I think you'll decide your gut was wrong, but there's only one way to be sure.


Well, if you read the linked article, a number of things are mentioned, including:

- union and intersection types

- an elegant and powerful representation of tuple and function types

- reified generics

- the cleanest solution to the problem of null

- awesome modularity

- a language module [that] completely abstracts the underlying runtime, and offers a set of elegant APIs that vastly improve on those available natively

- a language specification

None of which is offered by Kotlin.

That's quite a lot, actually.


- union and intersection types -- I'll have to read up on this

- an elegant and powerful representation of tuple and function types -- Okay, Kotlin could do with this

- reified generics -- This is apparently expensive on the JVM: http://blog.jetbrains.com/kotlin/2014/12/m10-is-out/

- the cleanest solution to the problem of null -- I think saying that `String? x = "abc"` is cleaner than `var b: String? = "abc"` is subjective. -- Does Ceylon have Safe Casts? https://kotlinlang.org/docs/reference/null-safety.html

- awesome modularity -- Something I'll need to look into

- a language module [that] completely abstracts the underlying runtime, and offers a set of elegant APIs that vastly improve on those available natively -- I guess the improvement in abstraction comes from the Reified Generics -- Have you got any examples of where the API is superior to that of the Kotlin one? For example, with Kotlin's extension functions Java File object has been extended with a readLines() function that returns all of the lines of a File as a List. I was impressed when I saw that. Underneath it is doing the usual BufferedReader and InputStream boiler plate work that you would normally write in Java.

- a language specification -- https://kotlinlang.org/docs/reference/


For the record:

- Kotlin does not have tuples, and doesn't allow abstraction over function -arity. So no, it can't to that.

- Reified generics are simply not expensive, at least not the way Ceylon implements them. But sure, Ceylon's reified generics were implemented by Stef Epardaud who is the best programmer I've ever worked with, so I can understand if some other people find them difficult to implement efficiently.

- I'm not talking about syntax. Syntax is uninteresting. I'm talking about semantics. In Ceylon, optional types are a trivial syntax sugar for a union type, not a hacked-in special case in the type system, as they are in Kotlin, and that means that I can do more with them, for example they naturally combine with union and intersection types to do useful things.

- Your link to documentation for Kotlin does not include any specification for the language. Do you know what the word "specification" means in this context?

Finally, I strongly recommend that you take the time to read the Ceylon documentation and inform yourself about the language. You'll find lots of really interesting ideas and information in there, and I'm certain you'll love the language!


The problem with reified generics isn't their efficiency, but that they don't play nice with other generic types on the platform (which is the vast majority).

Every choice in Kotlin's design has been intentional with one idea in mind -- compromise on purity in favor of interoperability (to lower the cost of adoption). So, of course you can do more at the language level with Ceylon, but Kotlin set out to do less in that arena by design. OTOH, Kotlin has several orders of magnitude more idiomatic (or very nearly idiomatic) libraries than Ceylon.

There's a very clear tradeoff here, and Kotlin and Ceylon have been designed with very different underlying philosophies. The only point you can argue about is which language gets you more bang for the buck. Kotlin has intentionally chosen less bang for less buck, while Ceylon has chosen the opposite. Personally I believe that almost all language-level abstractions are relatively low-bang[1] -- or certainly have diminishing returns -- and therefore language purity should always be compromised for almost any other extra-linguistic feature (if it's a language designed for the industry rather than academia), and so I think that Kotlin has made the better decision and gives you almost as much bang for far less buck. But only time will tell, and arguing about this at this point is just a matter of personal preference. I can certainly see some people preferring the one and some the other.

Another way to look at it is that Ceylon was designed to appeal to Scala people, while Kotlin was designed to appeal to Java people :)

[1]: By that I mean that they're always useful for something, but in the end have a low impact on total productivity (which includes more than just writing the code).


By the way, pron, as more general complaint, your comments about Ceylon are always very uninformed, but you state them as fact.

How about you actually spend some time learning the language first before commenting any more about it here or on reddit. Because it really wastes my time and raises my stress level having to correct your - probably unintentional - FUD. It's clear that you don't know Ceylon, so please stop telling everyone else stuff that you're just guessing at.

OTOH, if you want to get answers to any questions you might have you are extremely welcome to come on our Gitter channel and ask them, and I promise we're always very patient about explaining stuff there. I make that offer in complete sincerity.


I don't think they are uninformed, so feel free to correct me when I'm wrong. My "long-winded" comment wasn't about generic types -- just the first, small bit -- and that bit wasn't about Ceylon's generic types, but about generic reification on a shared platform like the JVM in general, which bakes a variance model into the class. As long as you're the only one doing reification you're sort-of fine, except all those erased generic types aren't quite first-class citizens. I should have clarified that.

As to the rest (and the lion-share) of my comment, I don't think it requires further clarification, and I don't see why you'd even think it's wrong. You've set out to create a new language with new, clean type semantics and a new runtime library, while Kotlin, in contrast, has had a different goal altogether. It doesn't even have its own concrete collection classes, so that's a radically different level of interoperability and a radically different design. That is the major difference between the languages rather than the list of features you've named in an answer to a question by someone else (and like I said, either approach has its proponents), so from my perspective it was you who was adding to the confusion, which I wanted to correct.

The answer to the question "what is the difference between Ceylon and Kotlin?" IMO (at least when the JVM target is concerned) is that Ceylon is a completely new "greenfield" language with a new, powerful type system, new semantics and a new runtime library, while Kotlin is "a better Java", a language preserving Java's semantics and standard library while solving its pressing shortcomings and providing a more modern syntax, and made to be adopted piecemeal into Java codebases. Of course there's some overlap, too, but that's the different in philosophies in broad strokes. In terms of features, some are similar (with Kotlin adopting some of Ceylon's ideas) and some are different, but that isn't the big difference.

For those reasons, BTW, while it would be very nice to have a Kotlin spec, it isn't as necessary, as most its semantics are borrowed from Java.

Of course, you may well think that those linguistic features are a bigger difference than the design goals, but I will disagree (due to the reasons I laid out in my other comment), and no amount of Ceylon expertise is relevant to that disagreement.


Well it should be very clear, that if you believe that Ceylon has a problem interoperating with Java's unreified generics, that you don't know enough about Ceylon to be able to comment with any sort of certainty on the topic of Ceylon and Java interop.

Because you quite obviously have never even tried it once.

That's clear, isn't it?


I didn't say that Ceylon has a problem interoperating with Java's unreified generics, just that reified generics on a shared platform have their own issues. The level of interoperability, though, is radically different from Kotlin's. And yes, I have never tried Ceylon because its stated design goals -- while great -- are not what I'm looking for. If I got the design goals and philosophy wrong I'll happily give it a try. I will also reiterate that I can certainly see that other people may prefer Ceylon's design goals over Kotlin's.


Now you're just lying. You said:

"The problem with reified generics isn't their efficiency, but that they don't play nice with other generic types on the platform (which is the vast majority)."

And the context of the comment was quite clearly Ceylon interoperating with Java as anyone can verify.

I have a friendly request for you: please don't comment about Ceylon on any more hackernews or reddit threads. It's great that you like Kotlin and are having success with it. I'm happy for you. Post about how great Kotlin is on all the Kotlin threads you like.

But it's just not a good thing for anyone that you're going posting on Ceylon threads, speculating about made-up problems with Ceylon, and pretending you know Ceylon when you don't.

So please stick to the Kotlin threads is all I'm asking, OK?


> I have a friendly request for you: please don't comment about Ceylon on any more hackernews or reddit threads.

This is really unproductive. Reddit and HN are discussion forums; what we want on them is more discussion, not less. We want high-quality, accurate, discussion, but if we're not getting that, the solution is to raise the quality, not reduce the volume.

In particular, the last thing i, as a reader of discussions, want is for a discussion forum to turn into a confederation of theocracies where nobody but the local priesthood are allowed to speak.

So, pron, i also have a friendly request for you: please continue to comment about Ceylon wherever you like - but make sure you've done your homework before doing so!

Specifically, if you could produce a concrete example of how Ceylon's reified generics interact poorly with Java's generics, that would be really interesting. If you could produce an example of how non-Ceylon reified generics interact poorly with Java generics, then that would be interesting, and gavinking could explain how Ceylon avoids the problem, which would also be interesting. And if you find that actually, there isn't such a problem with reified generics, that would be interesting too, not least for you.


Assume you have language with a generic type List<T>, and an instance, v, of the type List<Integer>. Can you then pass that value to a method expecting a List<Number> (assuming Number is a supertype of Integer)? Well, that depends on the variance rules of the language and the runtime. On the JVM, any type is checked both at compile time and at runtime. Erased generics, though, mean that the runtime type of v is just List, while reified generics mean that its List<Integer>. When a type is reified -- namely, its full type information is available at runtime -- the runtime needs to know the relationship between any two types: does one extend the other or are the unrelated? But with generics and variance, there is no "best way" to do variance and different languages may choose different variance models. Because the runtime has to know what is the relationship between any two types, the v variable has to know, at runtime, whether it is also an instance of List<Number> or not. This means that the same generic classes cannot be shared among different languages with reified generics, if they have different variance rules, because the language's decision is baked into the compiled class. That's what I meant in my comment. Languages on a JVM shouldn't have reified generics because then they may not play well with others.

With Ceylon, the issue is different, because the JVM -- unlike the CLR -- doesn't have a standard way of specifying reified generics (and that's a good thing, IMO, because of the "baked-in variance problem"). However, that means that none of the standard Java generic classes are first-class citizens in Ceylon world, because they don't have the reified runtime type information. This isn't a problem for Ceylon because one of its stated goals (it says so right on their website) is to replace the Java standard libraries, so this incongruence doesn't even matter to them because a Ceylon List and a Java List are not even the same type to begin with. That a Java list instance does not have a reified generic type in Ceylon is, therefore, not a problem for them, because Ceylon didn't set out to make the existing classes first-class citizens of its brand-new ecosystem.

This is why I and the Ceylon guys have this misunderstanding. They think I'm saying Ceylon has a problem, but I'm not. Ceylon has certain core design goals that may be what some people want but not others, that is all. But those design decisions do have ramifications.

BTW, the "baked-in variance" problem will not get introduced into the JVM with the addition of specialized generics for value types in Java 10, because value types can't extend other types, and so a List<int> can't also be a list of any supertype (or subtype).


>> none of the standard Java generic classes are first-class citizens in Ceylon world, because they don't have the reified runtime type information <<

This is just not true. In Ceylon when you import a Java generic class, you can do everything with it that you can do with the same class in Java.

Please stop posting incorrect things about Ceylon. You're coming off as a walking, ranting, personification of the Dunning-Kruger effect.


> you can do everything with it that you can do with the same class in Java

Of course! I have not said otherwise. I have said that you can't do with them everything you can do with Ceylon classes, hence -- not first-class citizens.

Now, I would appreciate you stop calling me names, because I haven't called you names. On the other hand, you have not addressed even a single one of the main points I've raised, except come back with great fury against some statements I've made that may not have been clear. So I would also appreciate you taking the time to understand what it is that I'm saying rather than what it is you think I'm saying, because I have not said a single bad thing about Ceylon in this entire thread (on the other hand, I have paid it and you several compliments because it really is a beautiful language), except that I believe a more compromising approach to language design would prove the more pragmatic one in the long term. Please try to understand what it is that I'm saying before blowing a fuse. We are in total agreement (on the facts, at least).

I joined this discussion to sound an observation about different design philosophies in language design (in rare agreement with a comment by Imm), then I commented to a user who asked about the differences between Ceylon and Kotlin (answer: different design goals), and you just keep calling names left and right and think I'm out to spread FUD or that I have an animosity against Ceylon. Jeez. So I will say it -- again -- just so there's no misunderstanding: Ceylon is a terrific programming language, and anyone whose goals are aligned with the language's goals should definitely give it a try!

If you think I have posted something that is incorrect or can be misunderstood, please add your correction politely. Why politely? Because you just might have misinterpreted my intentions or my words, and by being polite you might avoid saying things you may regret. Even if you really think that I'm trying to hurt your language or just so stupid that I keep making the same mistakes over and over, still keep a polite tone, because other readers of the discussion may not have the same interpretation as you.


> On the other hand, you have not addressed even a single one of the main points I've raised, except come back with great fury against some statements I've made that may not have been clear.

And this is why creators of languages should refrain from participating in discussions about the language they created. Especially when they post so much stuff and they seem to be the only person in the 100+ messages defending the language.

Either Ceylon stands on its own merits and other people will come to correct misconceptions about it or... there's simply not enough people who care about it.


Well, at least in this case, gavinking's protests were utterly unnecessary because I didn't attack the language (despite his beliefs to the contrary) so there was no need to defend it. I just wanted to clarify its clearly stated, official design goals, and later (after being called lots of names) also asked why the language designers think those goals are the right ones to address, because on the face of it, they appear to be the wrong ones to me. It is, of course, a matter of pure opinion and outlook, but still, it is interesting to hear the designers' views (especially because a new language is generally something that makes a much stronger statement -- ideological, philosophical -- than most developer-facing software products. Even if gavinking thinks I have misunderstood Ceylon's treatment of generics or the quality of the Java interop, those topics were really not the core of my statements, but rather Ceylon's basic raison d'etre.


Please get some help with your mental health issues.


> please continue to comment about Ceylon wherever you like - but make sure you've done your homework before doing so!

The issue with this type of comment is that we (humans) have a set of cognitive biases which often lead us to think that we've "done [our] homework" when, in fact, we haven't. Such a person would probably actually only absorb the first portion of the quoted sentence from your post.

(Sorry for the slightly OT.)


He did the same uninformed rants about other languages for a long time already. It's unlikely that he will do his homework any time soon.


What's unlikely is that you'll ever try to understand what it is that I'm saying when I talk about language design goals.


Seconding that.


Happily, as long as you don't misrepresent the difference between the languages.


Thank you, I appreciate it.


Thank you!


> The level of interoperability, though, is radically different from Kotlin's

There's no truth in that. Sure, it's possible that there are some differences in how we both do interop, and that some things are easier in one or the other, but overall you've no basis for claiming that, and I strongly suspect you haven't tried Ceylon for interop at all or you would not say that.

When you do try and find interop things that we should improve, please let us know in our issue tracker and we'll do our best to fix it.

Meanwhile, please stop with the FUD.


> Sure, it's possible that there are some differences in how we both do interop

There are no "some differences", but a radically different philosophy which is at the very core of the language's design. A Kotlin list is a Java list and vice-versa; a Kotlin map is a Java map and vice-versa; a Kotlin set is a Java set and vice-versa. The same, BTW, is true for Clojure, but unlike Clojure, Kotlin doesn't just keep the interfaces, but also the implementations. Kotlin hardly even has a standard library. The Java standard libraries are Kotlin's standard libraries (modulo some extension methods). Ceylon has its own standard libraries, and, in general, Java libraries are not idiomatic Ceylon libraries. That Ceylon even has CeylonList/JavaList types shows how the two approaches are worlds apart. Comparing it to Kotlin in that regard is ridiculous, and I don't even know why you'd try. It is one of Ceylon's strengths that it has its own library, and one of Kotlin's that it doesn't. Each appeals to different needs, and I don't see why you feel you should blur the differences.

> When you do try and find interop things that we should improve

It's not about that. You may think that Ceylon's Java interop is great. It may be just the right amount of interoperability that you want. But claiming it is anywhere near Kotlin's is just preposterous. I didn't say that Ceylon's Java interop is bad, but it's just not even in the same ballpark as Koltin's. But that's OK, because the two languages have different philosophies.

> Meanwhile, please stop with the FUD.

Please stop calling it FUD. I have never, ever said people shouldn't use Ceylon, that it's a bad language or even that Kotlin is better. I have emphasized the big difference in design goals between the two languages that makes them very different in practice: Ceylon has an advanced, very elegant, beautiful type system, while Kotlin has many thousands of libraries. Where is the FUD?

OTOH, instead of calling it FUD, and since this is a Ceylon thread, I would very much like to hear a justification for Ceylon's design; not the choices of the particular language features -- I will readily admit that Ceylon is the best language ever devised by man -- but why being better at the language/typesystem level, without offering a new paradigm warrants switching a language in the first place. After all, it doesn't offer anything radical when it comes to concurrency (like Clojure or Erlang or Go) or functional purity/equational reasoning (like Haskell). It's just cleaner and more elegant than Java or Scala. OCaml is another such beautiful, well-designed language, but, perhaps sadly, it has hardly seen any adoption. Why do you believe that is enough to get people to switch to a new language? For example, I know that Joe Armstrong thought a lot about the problem of fault-tolerant systems, and he came up with the idea of isolating failure; Rich Hickey thought a lot about state and identity and came up with Clojure's data structures and controlled mutation. Their reasoning is fascinating. What is that behind Ceylon's (I can tell you the reasoning behind Kotlin)? Did you reach the conclusion that a major obstacle to building modern software at this point in time is deficiencies in the type system? I'm not mocking, and I'm not saying it isn't, but unlike in Clojure's, Erlang's, Rust's and Kotlin's case (or Haskell or Scala), I've just never seen the Ceylon philosophy explained.

I've read Ceylon's guiding principles, but they haven't answered the question. If simply doing the same thing better justifies starting over, then supposing Ceylon takes off, in a few years Ceylon, too, will accumulate cruft, and its design mistakes (in the language or libraries) will become apparent. What will Ceylon advocate then? Backwards compatibility or breaking changes (or maybe a new language altogether)? And if the idea is to start over every 20 years -- I can see the merit in that argument -- why not a whole new paradigm? Is everything OK except mistakes in library design and the type system?

You don't have to answer, and you can either address or ignore my views -- but please don't call them FUD.


> But claiming it is anywhere near Kotlin's is just preposterous.

The only example you give is that they don't have their own standard library. I agree it's a difference, but you really think that makes it worlds apart?

I mean, in Ceylon you can also use the JDK, so I don't quite see the big thing, but even then, OK that's one difference (and it's a justified one too, but fine, OK). That's really the thing that makes you say that we have Java interop a world apart? I understand it may be an important point for you, but I don't understand how you can extrapolate that it's so important for everyone.

> while Kotlin has many thousands of libraries. Where is the FUD?

There. Right there ;)


> I agree it's a difference, but you really think that makes it worlds apart?

Yes. Well, it's one of the symptoms. Let me explain, but instead of using my own words, let me quote Ceylon's website:

Ceylon is a new programming language that's deeply influenced by Java, designed by people who are unapologetic fans of Java... 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... Java interoperability is a major priority for the project. However, since Ceylon will be based on its own modular SDK, making a clean break from the legacy Java SDK, Ceylon will require new frameworks designed especially for Ceylon.

In one of the comments, Gavin King, Ceylon's chief designer, explains what differentiates Ceylon from other attempts:

What's going to be very challenging is the _platform_: the libraries and frameworks. This is where most of the potential value of this project resides, but it's where we have relatively more work to do than other projects which simply aim to leverage the Java SDK "as is".

So (my words now), Ceylon is a new language with a new ecosystem. It is a greenfield project that also can interoperate with "legacy" Java libraries. Kotlin is fundamentally different, as Gavin Kind correctly notes. It's decided from the get go that the Java ecosystem is the Kotlin ecosystem. That any Java library is an idiomatic Kotlin library and will be treated the same way as if it were written in Kotlin (that goal has not been achieved 100%, but certainly 95%). That meant that any language feature that would have made the Java ecosystem different from the Kotlin ecosystem was intentionally left out. For Ceylon, the goal was different. A new better language and a new better SDK. When interoperability was concerned, wrapper types were introduced and sometimes language features (that are not recommended for Ceylon code) like use-site variance, too. That is a completely different perspective with major implications. Kotlin really does have many thousands of Koltin libraries; Ceylon doesn't. OTOH, Ceylon is a more comprehensively designed language with less compromises.

I can speak from experience. I'm the author of several Java libraries. Some of them have hundreds of API classes and thousands of methods. Making those libraries "Kotlin idiomatic" was zero effort, and adding all the necessary "Kotlin bling" (e.g. cool use of inline functions which are Kotlin's poor-man's macros) took a couple hundred lines of code, none of which were really necessary. Clojure, BTW, is similar, but less ambitious in that regard. As all Clojure collections are Java collections and vice-versa, Rich Hickey specifically said that Java libraries should not be wrapped, as many can be used as-is, simply passing in and getting out plain Clojure types. Ceylon is different. If I have a library working with Java collections (which is pretty much all of them), any use by Ceylon code would feel foreign and may require wrapping or other special handling. But that is by design. It says so right there on the Ceylon website. How can any of that be FUD?

> There. Right there ;)

I see. Then consider changing the Ceylon website because it's just full of FUD about replacing the ecosystem. I might be guilty of spreading it, but I'm not the source.


>> Then consider changing the Ceylon website because it's just full of FUD about replacing the ecosystem

It is not. You're a fabulist. Your behavior on this thread is worse than obnoxious.

>> I can speak from experience. I'm the author of several Java libraries. Some of them have hundreds of API classes and thousands of methods.

You can use them in Ceylon with no problems at all.

Please stop lying about Ceylon and please stop putting words in our mouths. Thanks.


Dude, I am quoting verbatim from your website. I have never said that you can't use Java libraries in Ceylon. I have said it is Ceylon's goal to replace Java's libraries, and that is lifted from your website. In fact, I don't even know why you're arguing, as you have not mentioned even a single point where you disagree with what I've said, yet you keep calling me a liar and a fabulist for some reason (for the record, I'm not). For all I know, we're in perfect agreement. What is it that I'm supposedly lying about? Have I misquoted Ceylon's stated design goals? Have I said that Ceylon's Java interop is bad? Ceylon's Java interop is radically different from Kotlin's because it was designed that way! You have clearly said that unlike other projects that want to work with the JDK as-is (Kotlin is one), Ceylon seeks to replace the libraries. You view that decision as a strength and place it high on the Ceylon FAQ, while Kotlin views the opposite decision as a strength. Both are fine, but the difference should be noted. It is you who is putting words in my mouth and insisting on arguing even though I don't even know what about. So unless you're willing to actually state what it is that you disagree with, please stop calling me a liar, thanks.


P.S. Ceylon's approach to Java interop resembles Scala's, which is yet another reason (aside from the adoption higher-order type-based abstractions) why I think Ceylon would attract Scala programmers, who are already fine with the approach.


Earlier today I, in all sincerity, invited you to our Gitter channel, where there's always people discussing this stuff night and day. That invitation is still there. You're welcome any time you like.


"The problem with reified generics isn't their efficiency, but that they don't play nice with other generic types on the platform (which is the vast majority)."

This is simply nonsense. You made it up. There have been zero complaints about problems Ceylon has in interoperating with Java's generic types, since they simply don't exist.

I can't believe you just wrote such a longwinded comment about a nonexistent problem that you imagined out of whole cloth.


Could you grossly explain how reified generics are implemented and how they interoperate with Java's generic types? It would be a good way to defuse pron's claim.


"Another way to look at it is that Ceylon was designed to appeal to Scala people"

This is quite clearly not true, and yet another assertion that you just made up and stated as fact. We're Java not Scala developers, and we designed Ceylon for other people like us. Don't try to tell me what my own motivations were.

In fact, it's very difficult to imagine, even charitably, why you would possibly be motivated to make such a claim unless you were deliberately trying to spread misinformation.


Yes, I did make that bit up. In fact, I misspoke, and I apologize -- that statement was wrong. What I really wanted to say is that Kotlin would appeal more to Java people while Ceylon would appeal more to Scala people, and even that is made up, but I still think it's true. How did I come to such an outrageous conclusion? By reading (with great interest and enjoyment!) blog posts by you about type functions in Ceylon. A fascinating topic (and Ceylon's handling of it is very elegant), but one which -- I believe -- appeals more to those who place much importance on such type-based high-order abstractions in their language, and less to those drawn to "blue-collar" languages.


As a former Ruby dev, and current Scala dev, I actually think Ceylon would appeal more to Rubyists.

Syntax-wise, Ceylon is not a very pretty language at first glance. LHS types and semi-colons. Not really a lot to like from a syntax perspective for your average Scala developer I think.

But that's just my opinion.


Could you please explain how the internal representation of null in the language's type system has any effect on the semantics of code written in that language?


Sure. So I'll give you one very over-simplistic example. Let's assume that T is an unknown type (a type parameter).

You can form types like Object&T, and if T is an optional type of form S|Null, then that is reduced automatically to the type S by the typechecker. But if T is not an optional type, then it just remains T.

Very useful to be able to do this kind of trick in generic code.

And note that nothing here was using any special reasoning about Null: this is all just the totally generic reasoning for union types in general.


Null in Ceylon is just another type, and nullable-X is just another union type, so you can use them sensibly with generics. With Kotlin if you want to write a generic method like "add two values" and have it handle nullness polymorphically then you have to think about it.


> - reified generics -- This is apparently expensive on the JVM: http://blog.jetbrains.com/kotlin/2014/12/m10-is-out/

FTR I am not sure I believe that explanation. I was with Gavin a few years ago when Andrey Breslav asked us if we were going to implement reified generics (we had not yet at the time) because they were having trouble implementing it and so if we were not going to implement it, they would not bother.

We haven't talked about this conversation publicly in the past because to be brutally honest most of it would make them look really bad, and it's likely that we won't, but this anecdote was very relevant to the discussion about reified generics.

My guess is they tried and failed, strictly based on this conversation. It's possible that they really considered it too expensive, but I since that's not backed by public experiments and our own experiments tell us it's not that expensive for the benefits it gives us, I don't _have_ to believe them ;)


-reified generics: From what I've seen, the Ceylon guys have done a good job of implementing this and they make flow-sensitive typing possible. Without out, the benefits of union types don't fully materialize. See http://ceylon-lang.org/blog/2015/04/19/observable/

- problem of null: Ceylon uses union types to union between the class in question (ex String) and Null, which is a type separate from Object. Therefore, the typesystem enforces this. And yes, Ceylon has the exists operator, which means you can do if (exists stringOrNull) to instanceof/cast at the same time.

- elegant APIs - With regard to file I/O: https://modules.ceylon-lang.org/modules/ceylon.io/1.1.0/doc

- language spec - Ceylon's is much more detailed: http://ceylon-lang.org/documentation/1.1/spec/html_single/


This is what a specification looks like:

http://ceylon-lang.org/documentation/1.1/spec/html_single/


Not the best place to mention this, but I never understood why, at least when talking with the functional oriented people, the union types are not explained as providing first level support for the Option, Either and the Try monads.


Well, I guess it depends on what you mean by "first level" support.

For example, the T|Null thing doesn't give you code composability of the type monad transformers do -- at least as far as I understand it[1]. (I'm sure there are other things, but that's the first thing that popped into my head.)

FTR, I am a typed-FP weenie, but I still find Ceylon quite interesting, though I haven't done anything non-trivial in it yet.

[1] I still haven't fully understood the (experimental) HKT support, so maybe that can accomodate this?


There are some places where monad composability would improve your code but in general, at least the way I see it, you can replace a scala for comprehension with a set of IF statements, each IF eliminating a wrong value (null, exception, etc). Not to mention that you can have as many options as you like (A|B|C|D|E), whereas the mentioned monads must be composed in order to capture the same thing.

But it's true I never built a big ceylon project, so I can't say I know how that works out in practice.


Yes, it's one good way to think about how they fit into the whole ecosystem of the language. Thanks.


> Well, if you read the linked article, a number of things are mentioned

The article was an overly verbose 2000 word wall of text.


What has happened to our culture? People are actually proud of being too lazy to read anything longer that a tweet?


I think it's a fair complaint, it is fairly dense and as something that's supposed to encourage adoption you might want to have a quick high-level summary.

On a slightly different note(and no idea if this goes against HN guidelines) but you've got a fairly argumentative tone. If you're really interested in seeing the language flourish I'd try not being as combative.

Community is just as important as how well a language is designed and based on the tone of a lot of the sub-threads here I'm not really inclined to look into Ceylon any further.


Alas, to his defense, it's slightly unnerving to read malinformed, biased critics all-thread long.

I would really advise him to try and ignore most of them if he wants to keep his sanity though. (serious, been there, done that.) Especially since I think that the language looks quite promising.

Sometimes, it's ok to correct things even if a little harshly though. People will always find a dumb argument anyway.


No, because that pattern is still strictly more powerful. With enumerated classes I can have cases which are a class rather than just a singleton instance.


So it seems to me that if you need multiple constructors then it's worth being able to give them names, in order to identify their purpose.

I have never looked at how Scala handles constructors, beyond being dimly aware that Scala has them, so I don't see why I should be expected to mention Scala, when it had no influence at all on the design of this functionality. To be clear, I find it highly unlikely that Scala constructors are very similar to what I describe in this post, except perhaps on the most superficial level. I will take a look at Scala later today to confirm that, just in case I'm wrong.

I'm not sure what argument is being made in the rest of your comment. Perhaps you could elaborate on what are your concerns?


Given you're a language designer, I'm really surprised you have not looked at Scala enough to know how it handles constructors.

Scala is also your biggest competitor (IMO) on the JVM, which makes it even more odd that you seem to not have looked at it deeply. (I'd understand not reading the latest DOT type calculus/whatever paper, but this is basic syntax/usage.)

Totally your call of course, but stealing the best ideas, in any endeavor, is usually the best way to go. Even if you decide to not steal Scala's constructors, that's fine, it's awesome if you have something better, but to have not even evaluated them...

Just surprised.


I guess I don't understand what you're saying here. I was already aware of the concept of a constructor, from years of Java. And I already had a set of really extremely tight design constraints in terms of the existing language syntax and semantics, including a set of principles about how the block structure of the language works, rules about definite initialization, the fact we don't have overloading, etc, etc, which are quite specific to _Ceylon_, and aren't found in other similar languages. These constraints were pretty much sufficient to fully determine the resulting design.

Furthermore, there was an issue open in Ceylon's issue tracker for almost 2 years, following on from discussions and proposals in two other issues that go back even further, and these issues were read and commented on by many of our community members, including some who have some Scala experience.

Now, if you could point to some cool idea in Scala that we obviously aren't aware of, and which could have improved the design of constructors in Ceylon, then I guess you would have a point. But it doesn't seem like you do have anything concrete, just a concern about _process_ rather than _outcome_.

And fundamentally I'm a guy who cares about outcome. And I think the outcome is rather excellent.


I think what they're saying is that it's good to give credit where credit is due.


Well since zero credit is due to Scala (read my post below where I utterly demolish the claim that Ceylon constructors are similar to Scala) then doesn't that seem like an utterly rude and obnoxious demand to you?


If that were the case, yes, but it isn't. There are obviously some differences but there are clearly also uncanny similarities.


Name the "uncanny" similarities please. If you can't, I might think you're trolling.

To be fair, it's nice to see you acknowledge that there are "obviously some differences". Some tiny little subtle differences like how in Ceylon, I can actually have two constructors that both initialize an immutable field. Like how constructor resolution is by (unambiguous) name and not by (potentially ambiguous) overloaded parameter types. Like how different constructors can delegate to distinct constructors of the superclass. 'Cos, y'know, other than that, it's really just a copy of Scala.

Absurd.


I assumed duaneb was referring to the whole idea of giving parameters to the class definition.


Wait, you're not talking about constructors here. You're talking about the idea of giving a class a parameter list? A feature that I independently came up with about 7 years ago, before I - or most other people - had even heard of Scala? And then implemented 5 years ago as one of like the very earliest features in the Ceylon type checker? And which is not actually the topic of the linked blog post? You're calling me out for copying that?!

Man, seriously, there is such a thing as two people coming up with the same good idea independently. If you can't imagine such a thing happening, I'm at a total loss.


Certainly, it happens all the time. Leibniz and Newton invented calculus at the same time. Scala is 12 years old though, and it's rare for a language designer to not be aware of the main competitor in the same space, which is probably why people assumed that you were aware of Scala.

Note that I personally couldn't care less who invented what, I just wrote what I thought duaneb and stephen were getting at to clear up the confusion since you said "I guess I don't understand what you're saying here."


I think in this thread you're conflating taking credit with mentioning, which are two very, very different concepts. I would not expect you to give credit, but I would expect you to mention relevant competing technologies for a compare and contrast. :)


If you look above in this subthread you'll see the following comment:

> I think what they're saying is that it's good to give credit where credit is due.

I don't think I was conflating. Or at least, if I misinterpreted, then so did at least one other person. Which suggests that the original comments were very open to such an interpretation.


> But it doesn't seem like you do have anything concrete, just a concern about _process_

Yes, just for clarification, that was my point.

You're certainly having to defend yourself a lot in the other comments, so I don't want to continue that.

The order of Ceylon initialization is nice. That is a pita in Scala.


> Yes, just for clarification, that was my point.

OK cool. Then my response is simply that we took a whole lot of community feedback, as always, over a span of years, both on the issue tracker and on our Gitter (previously IRC) channel. People with a wide range of programming experience contributed to this discussion.

No, I did not look closely at Scala's constructors. I did look at some other languages which are a bigger influence on me, some of which do things very differently to Ceylon.

> You're certainly having to defend yourself a lot in the other comments, so I don't want to continue that.

Thanks :-/


So if you scroll down, you'll find my tentative evaluation of Scala's support for constructors. I have not found anything of interest there. Indeed, if my understanding is correct, constructors in Scala have extremely limited capabilities, since all initialization ultimately flows through the primary constructor which is responsible for initializing all fields. In Ceylon we obviously had a more ambitious set of requirements.


> Indeed, if my understanding is correct, constructors in Scala have extremely limited capabilities

Is this not desirable? The wider the definition of a constructor is, the less you can determine from looking at the construction of a resource/variable/whatever. When you delve into e.g. the creation of an ORM this becomes extremely important because it has to reason about data constraints across multiple initializations.


Wait, wait, wait: just two hours ago you were demanding that I give credit to Scala for the design of constructors in Ceylon. And you accused me of quote "just tweaking of the language's constructor patterns and calling it novel".

It seems that you now accept that in fact the two designs are dissimilar, and that Ceylon's is significantly more powerful.

So, before continuing this discussion, do you think it would appropriate to start by apologizing to my team?

Just so we don't get off on the wrong foot?


> just two hours ago you were demanding that I give credit to Scala for the design of constructors in Ceylon.

No, I demanded you reference a similar language to actually compare the benefits of your changes. If you do, I suspect you'll find you gain virtually nothing.


You wrote:

> Much of the rest of the work seems to mirror what Scala did several years ago, and this seems to nearly replicate that.

I have already demolished this claim on this thread, as you very well understand.

I personally make it a policy to admit error when I err. It's up to you to decide whether this is also your policy, or whether you prefer goalpost-shifting and prevarication.

> No, I demanded you reference a similar language to actually compare the benefits of your changes.

I make it a firm policy to not talk about other new languages when I blog about Ceylon, because whenever I have mentioned Scala in the past, even just in passing, I have found myself the subject of quite vicious personal attacks. I'm going to continue with that policy, this thread notwithstanding. But thanks for your feedback anyway.


> I make it a firm policy to not talk about other new languages when I blog about Ceylon, because whenever I have mentioned Scala in the past, even just in passing, I have found myself the subject of quite vicious personal attacks.

I'm sorry to hear that. That's certainly not a productive way to have a conversation, though, and it's rather confusing you'd try to argue for the benefits of your hard work without making them in terms of languages people actually use.


There is a large overlap between what you call the default constructor and scala case classes—there is a primary "value" parameter list, and other constructors must be defined in those terms.

My comment was not meant to be an argument, just a note that there are similarities between this and the other major contender for "java/javascript replacement" and you don't bother to mention them. If they are different, you don't bother to say that either. So it's not a very useful without the comparison, it's just tweaking of the language's constructor patterns and calling it novel.


Wait, Scala's "case classes" are an implementation of what are called "sum types" in PL theory. Ceylon also has sum types, but they don't have anything much at all to do with _constructors_.

If you want to know about how Ceylon supports sum types, you can look here:

http://ceylon-lang.org/documentation/1.1/tour/types/

FYI, Scala didn't invent sum types, and they can be found in languages much older than Scala, going back to the 1970s, if I'm not mistaken.

Finally, I don't understand why you're repeating the claim that we're "just tweaking of the language's constructor patterns and calling it novel" when I've already responded and explained that the approach to constructors in Ceylon is quite different to Scala and wasn't influenced by Scala. Is it just a lame attempt to try and provoke me or do you have an actual point to make?


Not sure what scares me more: A language designer which doesn't want to give credit where credit is due, or a language who really didn't do his research.

Too bad that Ceylon/Dart still haven't caught up with the state of the art in terms of "named/default constructors".


OK, well it seems quite likley you're just trolling me here, but I'll respond anyway: do you have some technical feedback on how the design I've outlined here is flawed or inferior to some other "state of the art" design, or a link to some research that you think I didn't do?

Because if not, it doesn't seem that scary, does it?


The whole idea of "let's encourage people to litter their classes with convenience constructors" is bad.

Constructors are the odd things which act like static methods, but have access to the fields of the instance-to-be-created.

Because constructors are weird and special in a lot of other ways too, it makes sense to use them only for initialization, and try to encourage people to define exactly one constructor.

Named constructors are poorly designed factory methods with the disadvantage that they are married to the class and add additional baggage to class declarations.

Why does Ceylon have objects, if they aren't used for one of their prime use-cases?

"Static methods go into objects, except static factory methods, let's keep dumping them into the class declaration" ... looks quite questionable to me.

Ok ... I'm really starting to believe you when you said you didn't look into that other language, because there is practically no benefit in doing it the way Ceylon does.


Well in fact constructors aren't that much like static methods at all. Now static methods really are a weird thing, because they break the block structure of the language: they look like they have access to members of the class, but they don't.

That's why Ceylon doesn't have static methods.

Constructors, OTOH, actually fit in with the block structure of the language. They do have access to the members of the class, and the responsibility to initialize those members.

Now, the interesting thing is that I spend 4 years of my life hoping that we would not need constructors, and that the ability to initialize a class via the parameter list of the class would be sufficient for all usecases.

Sadly, it turns out that I was wrong about this, and that, in practice, there are some really good usecases for constructors in a language which emphasizes immutability as Ceylon does. That's just what we ran into in practice.

> you said you didn't look into that other language

I never said that. Please don't put words into my mouth.

FYI, I've looked closely at lots of other languages, including languages like OCaml and F# and Rust which do things quite differently to Ceylon. I like those approaches, and they have advantages/disadvantages compared to constructors. I would not say they are clearly better, nor clearly worse. But I'm confident that what we have done is very clean and elegant and powerful in the context of Ceylon.


Yeah, OK, I just had a quick look, and Scala constructors seem to have almost nothing in common with the design I outline in this blog, other than being, well, constructors. Perhaps you didn't read the linked article?


Could you outline the differences between Scala and Ceylon constructors, for readers not familiar with both?


Yes of course. I'm at the gym right now, so give me a chance to get home, read up on Scala so I can be sure I'm not saying anything wrong, and then I'll reply. Is that OK?


Please look at "case classes" and their associated constructors, which is where I see the most similarity. I am sure they are implemented very differently, but I am not sure exactly what the benefits of ceylon might be over a more "cluttered" scala-style approach built on top of java class-and-interface MRO.


The equivalent of Scala's case classes is an enumerated class with an "of" clause. Constructors aren't really relevant here, AFAICT.


Of course! No need to rush.


OK, so, here’s a tentative list of similarities / differences. Please correct me if I've made a mistake.

Similarities:

- Scala has the notion of a “primary” constructor vs “auxiliary” constructor, which at first looks sorta superficially similar to the notion of a “default” vs “named" constructor in Ceylon.

- Both Ceylon and Scala (and Java, and C++, and C#, etc) have a notion of delegation between constructors.

Differences:

- In Scala, constructors are overloaded, that is, they are distinguished by the types of their parameters. In Ceylon, they have distinct names, and are distinguished by name.

- In Scala, every auxiliary constructor of a class must ultimately delegate to the primary constructor. In Ceylon, there is is no such restriction. Any constructor may delegate directly to the superclass. Given this, I can't see how it's possible for two constructors of a Scala class to delegate to different constructors of the superclass. That's possible in Ceylon.

- In Scala I could not find any way to assign to an immutable member (val) from an auxiliary constructor. At first I thought that this could not possibly be a real limitation, but, checking stack overflow, it seems that it is. Auxiliary constructors can only assign to vars? Really?!

- In Ceylon, initialization flows from the top of the class body to the bottom, allowing. In Scala it jumps around: all statements of the primary constructor are executed, even statements that occur after the auxiliary constructors, and then the auxiliary constructors.

- Ceylon has the notion of a partial constructor which partially initializes the class, but may only be called by other constructors. Scala doesn’t seem to have this concept. Indeed, the primary constructor must initialize all fields. And, if I understand correctly, the only thing that auxiliary constructors are allowed to do is mess with mutable members and perform side-effects. (Of course, it’s a bad practice to make constructors side-effecty.)

- Ceylon has the notion of a value constructor. I have not yet found anything like that in Scala.

- Taking a reference to a constructor and treating it as a function seems to be quite uncomfortable in Scala. In Ceylon it's very natural. Also Scala sometimes seems to demand the use of the "new" operator in instantiation expressions, though I'm not clear why that's a requirement.

My bottom line conclusion is that constructors in Scala are much less powerful than I had imagined they would be, and, it seems, much less powerful than constructors in Ceylon. Of course, some of what I’ve written here could be incorrect, since I’m not a Scala programmer. If so, I’m hoping someone will correct me.

Anyway, I definitely haven’t found anything in Scala constructors that we should have reproduced in Ceylon. Can someone else find something?


Looks like you are missing the point completely with your focus on Scala constructors:

Less is more. Nobody needs or wants the mess of Java-style initialization Ceylon tries to replicate.

  Ceylon has the notion of a value constructor.
  I have not yet found anything like that in Scala.
Yet another static thing in class declarations? Inventing different names for "static" doesn't solve the issue that you have introduced both "static" and "object" into the language. That's not a good idea.

  Also Scala sometimes seems to demand the use of the "new" operator in
  instantiation expressions, though I'm not clear why that's a requirement.
It's the same reason why instanceOf/casting is x.isInstanceOf[X]/x.asInstanceOf[X] instead of adding "convenience" syntax. You can't discourage people to use something and then provide syntax sugar for it.

Constructors in Scala are intended to directly initialize fields. They shouldn't be called directly, and are often private. Factory methods provide everything else, and are declared in objects, instead of being static like in Ceylon. That's by-design.

Because you care about the "outcome", not the "process": Scala did away with 90% of the mess associated with constructors, and used existing general-purpose features of the language to provide the rest (instead of having to introduce named constructors, default constructors, value constructors, partial constructors, and constructs which are "static" but named differently ...).

I don't think anything can change your idea that the thing you invented is the best thing ever (and everything else doesn't apply, because of the special constraints of Ceylon), therefore have a nice day! :-)


> Nobody needs or wants the mess of Java-style initialization Ceylon tries to replicate.

Initialization in Ceylon is nothing like initialization in Java:

- For the simple (common) case where there is exactly one initialization path, Ceylon is far less verbose.

- In Ceylon, the compiler guarantees that ever field not marked variable is assigned exactly once.

> Yet another static thing in class declarations?

Not really, just a constructor with no parameters.

Constructors are not "static". Constructors access the members of the class.

> Constructors in Scala are intended to directly initialize fields.

But it seems to me that they can't. Isn't it correct that only the primary constructor can initialize vals?

> Constructors in Scala are intended to directly initialize fields. They shouldn't be called directly, and are often private.

AFAICT it is not a limitation of the Scala language that constructors shouldn't be called directly. If it's indeed a practice that constructors aren't called directly, then it's interesting to enquire why that might be. And indeed an answer presents itself: because they don't have names.

> Factory methods provide everything else, and are declared in objects, instead of being static like in Ceylon.

Wait: a factory method declared on a "companion object" is not like static?! Really?

And it seems to me that people probably hide constructors behind factory methods precisely because constructors in Scala don't have names. I mean AFAICT, the syntax for calling a factory method of a companion object in scala is exactly the same as the syntax for calling a constructor in Ceylon! You just have to go through a whole lot more ceremony in Scala.

> Scala did away with 90% of the mess associated with constructors

And, AFAICT, also lost like 75% of their capabilities. Unless my evaluation above is wrong, and I'm missing something. But so far no-one has spoken up to correct me.

> therefore have a nice day! :-)

You too!


  Constructors are not "static". Constructors access the members of the class.
That doesn't mean that they are not "static". Yes, they sit in a weird middle-ground, but fact is that constructors are called on the class/type, and not on the instance.

  Color foo = ...; new foo; // doesn't make any sense.


  If it's indeed a practice that constructors aren't called directly, then it's 
  interesting to enquire why that might be. And indeed an answer presents itself: 
  because they don't have names.
No, because it is good design to have one entry-point to create an instance, not 5. It is hard enough with reflection, sun.misc.Unsafe and serialization as-is.

  Wait: a factory method declared on a "companion object" is not like static?! Really?
In Scala you have one place for "static" things. In Ceylon, static is all over the place:

  - Static members inside objects
  - Static methods inside classes (with new x() {...})
  - Static fields inside classes (with new x {... }


  I mean AFAICT, the syntax for calling a factory method of a companion object in
  scala is exactly the same as the syntax for calling a constructor in Ceylon!
Yes. Ceylon wasted the "good" syntax on the wrong construct. Most of the patterns leveraged in factory methods are just not available in Ceylon, because the best syntax was directly married to the class.

  And, AFAICT, also lost like 75% of their capabilities.
Which has not been a issue in the last 10 years of Scala. Everything Ceylon has built into "constructors" are just standard methods with no magic required in Scala.

  Unless my evaluation above is wrong, and I'm missing 
  something. But so far no-one has spoken up to correct me.
Yes, you are focusing on the power of constructors. Yes, constructors are not extremely powerful – because they don't need to be in Scala. You are missing that Scala provides that power without turning constructors into such a mess.


> fact is that constructors are called on the class/type, and not on the instance.

But this is the case in Scala too. So I really don't understand the distinction you're trying to make.

> No, because it is good design to have one entry-point to create an instance, not 5.

I don't understand how having a factory method on a Scala companion object that calls an overloaded constructor of a Scala class is not a separate "entry-point". I count each of those factory-method-constructor bundles as one entry-point. And even if these factory methods all call the same constructor, they still seem like separate "entry-point"s.

And apart from your assertion that a single "entry-point" is good design, I don't quite see any particular reason to believe it. You've offered no arguments for this assertion.

> In Scala you have one place for "static" things. In Ceylon, static is all over the place:

Scala has members of objects and constructors of classes. Ceylon has members of objects and constructors of classes. Where is the difference? OK, so in Ceylon I can have a constructor which does not declare any parameters. How does that amount to being "all over the place" compared to Scala.

> Yes. Ceylon wasted the "good" syntax on the wrong construct. Most of the patterns leveraged in factory methods are just not available in Ceylon, because the best syntax was directly married to the class.

Well you see this is where Scala starts to look really bad. The problem is that Scala has no plain functions. Scala forces you to write methods of objects. In Ceylon we have toplevel functions, so we just don't need to go around sticking functions on the side of classes like you do in Scala.

> Everything Ceylon has built into "constructors" are just standard methods with no magic required in Scala.

This is simply false. You can't emulate constructors with plain methods in a language which enforces immutability / single-assignment. If you could, we would have done it that way.

> Yes, constructors are not extremely powerful – because they don't need to be in Scala.

Well, I never claimed that Scala needed constructors. Indeed I never mentioned Scala until people started trying to say—incorrectly to the point of absurdity, as it turns out—that Ceylon had copied its system of constructors from Scala.

Indeed you were one of those people. You entered this discussion with the following attack on me:

> A language designer which doesn't want to give credit where credit is due

I'm still waiting for you to retract that, now that I've conclusively demonstrated that Ceylon's constructors are totally different to—and more powerful than—Scala's.


    A language designer which doesn't want to give credit
    where credit is due

  I'm still waiting for you to retract that, now that I've 
  conclusively demonstrated that Ceylon's constructors are 
  totally different to—and more powerful than—Scala's. 
Eh. What?

A) You conveniently left out the other part of the sentence.

B) I already commented on that topic very early on, and clarified:

  Ok ... I'm really starting to believe you when you said you 
  didn't look into that other language, because there is 
  practically no benefit in doing it the way Ceylon does.
To which you – confusingly – replied with:

  I never said that. Please don't put words into my mouth.
So what do you actually want?

  Ceylon's constructors are totally different to—and more 
  powerful than—Scala's
Yep. I didn't deny that. It's a good thing though, because Ceylon's approach isn't very good in terms of language complexity.


I never said I've never looked at Scala. I think you can tell from my responses to you in this thread that I'm in fact quite knowledgeable about Scala. What I said was that I had not looked closely at how Scala does constructors and that they were not an inspiration behind the design of constructors in Ceylon.

Whatever, your attack on me was totally uncivil and unjustified, as you now realize, which is why you're backpedalling it so furiously. You've never interacted with me before, and so coming in here with a blazing personal attack was completely unreasonable behavior. I think you see that, so let's just drop it now.

> Ceylon's approach isn't very good in terms of language complexity.

Here's another assertion for which you simply have not provided evidence. How are Ceylon's constructors more "complex" than Scala's constructors? The actual syntactic weight of both constructs is almost identical. And in terms of complexity, the factory-method-on-a-companion-class pattern is significantly more complex in terms of ceremony than doing the equivalent thing in Ceylon.

Look man, stepping back a second, I can see that you're clearly a fan of Scala and that Scala is something you love and enjoy. That's great! But Scala isn't perfect and other languages can have good ideas too. I highly recommend you spend some time learning Ceylon, since it has a bunch of awesome things in it that I know you'll love: the things we can do with union and intersection types, disjointness, abstraction over tuple and function types, etc, are just beautifully elegant and powerful. Don't let the fact that you love Scala blind you to other ideas.


  the things we can do with union and intersection types, 
  disjointness, abstraction over tuple and function types, 
  etc, are just beautifully elegant and powerful. Don't let 
  the fact that you love Scala blind you to other ideas.
I don't think it's a blind love, but all those things will ship in one of the next versions of Scala, too.

Given there are some things I can't just suffer anymore, like unreadable Generics (<>), required ; and "Type ident" syntax, maybe Ceylon just isn't for me. :-)


> I don't think it's a blind love, but all those things will ship in one of the next versions of Scala, too.

Well it's really lovely and encouraging to see Ceylon exercising such a strong influence on Scala. Makes me very proud.


Sorry, but I don't understand your point about instanceof/casting and how this relates to constructors. Please elaborate.


Things that are discouraged don't receive the language's nicest syntax.

(Secondary) constructors are discouraged.


What well-designed language doesn't do this?


Ceylon and Kotlin are two languages who did this (both instanceOf/cast and instance creation).


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: