Have they tightened up the floating point semantics? Or do you still get different rounding behaviour on the JVM, dart and JS?
I want to like Ceylon because it's the language Scala should be (assuming that higher-kinded types made it in - I could never work without them). It's Scala with all the ugly parts polished away, Scala with ten years' progress in language design.
But it does nothing that Scala can't. Scala might need a pile of bodges to offer these things - Shapeless implicit macros to use tuples generically, type-level libraries abusing the implicit resolution rules to implement unions, a retrofitted JavaScript backend. But that stuff has been written now, and as a developer it works - maybe with a couple of ugly extra lines here and there, but that's all.
I'm glad it exists, but I just can't see people choosing the more polished language over the one with ten years worth of library and tool support when there's no USP beyond that polish.
A language without higher-kinded types or type-classes cannot be the language that "Scala should be". And these aren't things that can be easily added later. And I don't think it will ever happen. And don't get me wrong, but software is about trust and I do not trust somebody like Gavin King for delivering a good language after Hibernate :)
> Shapeless implicit macros to use tuples generically
What can you do in Ceylon about this? Or are we talking about a dream?
> a retrofitted JavaScript backend
Not sure what you mean. Scala.js is reusing the Scala compiler in what happens to be the cleanest transition I've seen to such a different platform. And compared to other Javascript compilers, like ones for Ocaml or Haskell, this one actually works well and stays up to date. Care to explain?
> A language without higher-kinded types or type-classes cannot be the language that "Scala should be". And these aren't things that can be easily added later. In other words I don't think it will ever happen.
I mentioned higher-kinded types; last I knew they were an experimental feature. I thought Ceylon offered some way to do "open interfaces" (the vital part of typeclasses IMO)? If not then that's definitely an issue.
> And what can you do in Ceylon about this? Or our we talking about a dream?
In Ceylon you have arity abstraction over tuples built in, so you can do HList-style operations by default. Scala will supposedly add this in Don Giovanni but in the meantime you have to use Shapeless with its implicit macros and it's slightly less nice (e.g. the error messages are less clear).
>Scala.js is reusing the Scala compiler in what happens to be the cleanest transition I've seen. Care to explain?
I think it's fair to call Scala.js "retrofitted", and I think the article is right that a language that was designed from the ground up to be JVM-independent will inevitably be better at it.
My whole point was that these are minor rough edges to Scala that aren't really that important, so I'm not sure why you're being so defensive.
> but software is about trust and I do not trust somebody like Gavin King for delivering a good language after Hibernate :)
Perhaps it's just a joke, but if it's not: sure you're entitled to dislike Hibernate and prefer other ways to talk to a DB, but it's still one of the most widely used ORM on the JVM so it may not be perfect but it is also a huge success.
> A language without higher-kinded types or type-classes cannot be the language that "Scala should be"
You don't really get to say what other people think Scala should be. You like higher kinds, so do I, I'm glad they are in Scala but most people have never even heard the term and to them, they would much rather have a language with fewer features than one with more.
That's the goal that Ceylon and Kotlin are trying to achieve.
Scalajs is reasonably good, but it is retrofitted; it's a javascript backend for a language that wasn't specifically designed for a javascript backent. Ceylon was designed to compile to javascript. I haven't used either so I can't comment as to whether it actually makes a difference.
One place where it makes quite a big difference is in the standard library. In scala the standard library is very often just a thin shim on top of the JVM equivalent... which means that scala.js needs to shim the JVM library. It's not a huge deal in that most everyday things pretty much work out of the box, but if you're using a lot of time/date manipulation (via Joda-Time or the JDK8 java.time package) you'll have to use something else on the JS side.
Why is reinventing the wheel considered a good thing?
javax.time is considered by some to be one of the best, most well-designed general and versatile libraries for date and time related matters out there, regardless in any language.
How would things be improved by throwing that away, and inventing something different?
I think keeping the API and providing an implementation for Scala.js is a much more reasonable approach.
Designing a date/time requires very rare skills and knowledge that most people lack.
A re-implementation of javax.time means all the documentation, tests and existing code can be re-used and allow correctness checks against the existing implementation.
> Why is reinventing the wheel considered a good thing?
It's not. There just is no shim for java.time currently! Even worse, there could be licensing issues[1].
EDIT: That, and some of us are unfortunately still on JDK7 until the next Ubuntu LTS. Not that that's scala.js's fault, but it's a practical issue.
EDIT: ... and of course having a duplicate implementation of java.time (JDK + the shim-which-is-basically-a-reimplementation-in-JS) could be considered "reinventing the wheel"! :) If you have to reinvent the wheel, then doing it such that it at least behaves completely consistently across all backend platforms is preferable, IMO.
As mentioned in the ticket, the original implementation is BSD.
Your last point is not the only thing that matters though.
If the runtime already ships with packages X, there is no point in shipping your own implementation.
(Which is exactly what Scala/Scala.js does with math stuff: it reuses BigInteger from the runtime on the JVM, but ships its own implementation with Scala.js.)
Right, but the JS and JVM runtimes have quite different behavior. And I'm willing to bet that implementing something as non-trivial as java.time again in Scala(.js) will end up causing quite a few bugs because they aren't identical.
That's why I'd rather have a single implementation for anything non-trivial and just retarget that to each backend using more low-level primitives. After all you're using a different language -- using a different date/time API shouldn't be much of a problem.
Yeah, inventing an API and implementation of a date/time/calendar library from scratch without an existing spec, implementation, tests or experience will surely be totally bug-free.
I'm not saying it'll be bug-free. My point is that it'll have exactly the same bugs on either platform. This may be preferable to having different bugs on different platforms.
That's a good point. As a (shim) library developer I think I might agree -- because it would perhaps be easier to find bugs in my library -- as an application developer I wouldn't because I would have to find different workarounds for different bugs.
> I want to like Ceylon because it's the language Scala should be
> but I just can't see people choosing the more polished language over the one with ten years worth of library and tool support when there's no USP beyond that polish
It seems all a matter of time. What would Ceylon look like to you after some years of library and tool support?
The thing is Scala will always be 10 years ahead. I see Ceylon's future as looking like e.g. D - a better language than the alternatives in its niche, but without a USP to justify migration.
I don't think the assertion is that Scala won't be superceded.
I think the assertion is that it is not obvious why it would be superceded by Ceylon. So, if there's no obvious reason to move to Ceylon, who is going to get the ecosystem to a level that it will compete with Scala's?
Now, I personally wouldn't be so bold as to suggest that it will always be 10 years behind Scala. I have no idea. But it isn't clear why the language itself is offering sufficient advantage.
More likely, at least to me, is that some of the ideas that Ceylon's shown are practical e.g. union and intersection types, will find their way into more languages because of it.
Of course, someone could produce the next big thing in it tomorrow and do for Ceylon what Rails did for Ruby. Then I'd go find a hat to eat.
Don't forget that, running on the JVM with great interop means that any Ceylon program has instant access to a huge ecosystem, including not just Java libraries but also Scala libraries. I was able to use Apache Spark in Ceylon ;)
Again, I don't think anyone is suggesting that jvm languages can't be successful. The evidence would be against anyone who did.
The question is: why would you use Ceylon over the competition?
There are a number of reason I can think of. You want to target node.js too; you're a Haskeller in your spare time. That sort of thing.
But the question still stands. Is there enough to prefer it to Scala, Kotlin or, gasp, Java?
Honestly, I don't know. But equally there's nothing that stands out for me. If anything this has actually made me think I should probably look at Kotlin again.
I dabble with whatever new languages come out as any other language geek, but at work it only matters the languages validated by the IT department or requested by the customer.
So, like many, I only work with languages blessed as first class languages in vendor SDKs.
With Scala and Clojure barely being adopted by most Java shops (in perpetual terms), I don't see where Ceylon might fit in without a story to sell.
One feature of Ceylon that caught my attention however is that Ceylon modules are implicitly OSGi modules. If you are building a microservices-type JVM application based on OSGi, Ceylon could make this a lot easier.
I think it's part of a general trend of language designers (and even language fans) not understanding what makes languages work in practice. For academic languages this may not matter, but if you actually want your language to be used, you need to pay attention. A recent study[1] has shown that "extrinsic" factors (performance, tooling, familiarity, libraries) matter a lot more than intrinsic factors (syntax, abstractions) when it comes to adopting programming languages. A language that understood this beautifully was Java[2] (and, I believe, Go, which is very much in the spirit of the Java philosophy), that analyzed existing "advanced" languages like Scheme, Self and Modula (and indeed some of the people involved with those languages were among Java's early designers) and realized that the features that give those languages most bang-for-the-buck weren't clever abstractions but extra-linguistic features such as GC, dynamic linking and JITs[3], that can be packaged in a crude, "blue-collar" language that's familiar (and familiarity is indeed among the top factors in choosing a language, while "correctness" -- as in more powerful type system -- and particular language features are among the last). James Gosling called it a wolf in sheep's clothing. A wolf in wolf's clothing may look more fierce, and the sheep's clothing may indeed limit its maneuverability a bit, but it can still be almost as wolfish, yet much more palatable.
OTOH, Kotlin took whatever it could from Ceylon (the nullability types, flow-sensitive typing) while keeping 100% seamless interoperability with Java as the top priority, so it may not be a revolution, but its adoption costs are virtually zero. It doesn't even have much of a runtime library; it was designed in such a way that all cool features could be applied to Java's standard library. The idea was that abstractions are great as long as they don't come at the expense of more important features, such as availability of libraries, tools etc (Kotlin even supports Java's annotation processors, so popular libraries that rely on compile-time verification/code-generation such as Dagger can work on Kotlin code).
Of course, I take this much further than you and believe, unlike you, that the contribution of advanced language-level abstractions is not so pronounced at all (or, at least, it hasn't been shown to be significant), and obviously I have a very different perspective on Scala than you, but at least we can agree on something :)
[3]: Sun had experimented with a JIT for Self long before it was introduced to Java, and the plan was to make Java exploit JITs almost from the get-go.
I think Go is a disastrous misstep (at least in the system-software contexts where I have to deal with it--obviously, you can do whatever for app languages), but I feel like your points as far as Java/Kotlin go are really well-put. I am honestly surprised at how happy I've been using Kotlin as the baseline server language for my current project (the backend of a fairly intricately orchestrated SaaS). I was not prepared to like it as much as I have; it's still very, very Java, but it blunts the worst parts of it from a syntactic and, where it can, a semantic perspective. Like--List<T> is readonly, but retroactively applied to java.util.ArrayList, similar to IReadOnlyList<T> in .NET. It's pretty nice. I am a Scala person, or I'd like to be but I find I write unmaintainable junk in it; Kotlin provides many of (though not all; I desperately want real traits, interfaces are not sufficient) the features from Scala that I need, without many of the negatives of Scala.
The biggest downsides I've encountered are around the deeper-magic Java interop, with stuff like Dropwizard's HK2 dependency injection system getting a little messy--especially around non-nullable parameters--but that stuff is, all things considered, a small part of the application.
Yes, and that is really important when it comes to language use. The more people who use the language, the more it can develop and the more libraries that can be built for it.
The other advantage of Kotlin is that it builds on top of the existing Java code base. Java has had decades to build up an ecosystem of frameworks and libraries. Kotlin builds on these with excellent interop.
I like Kotlin too but in fairness this is a Ceylon thread ;)
From what I can see, Ceylon has a blend of strengths that should make it appeal to a certain segment of the market. On one hand, it's a fresh start and has a lot of the cleanness and terseness that I like from Kotlin. On the other, Gavin is clearly very much into type systems and type theory, and Ceylon has a more complex/powerful type system than Kotlin does.
I'll admit that I'm not totally sure whether the additional complexity is worth it, but I'm very open to being persuaded.
So it seems to me like Ceylon should appeal to people who currently like Scala or Haskell and push the type systems to the limit, but really want something without historical baggage like XML literals and other oddities. And I'm sure there are plenty of programmers like that.
The real question will be interop costs. Kotlin doesn't have any and that's the main reason people can consider it in existing projects, or introduction inside large corporations. Ceylon takes a more Scala-like approach where it has its own standard library, its own collections, etc.
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.
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.
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).
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 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.
Ceylon has an IntelliJ plugin in the works that builds on the solid foundation of the Eclipse plugin, so it's picking up features really fast. It should be out in a few months.
> I think it's part of a general trend of language designers (and even language fans) not understanding what makes languages work in practice.
Maybe, or maybe not all language designers have the goal of making their language as popular as possible. A language can be popular enough, such that it has a good community and good set of libraries, without trying to get everyone to switch.
In fact, depending on what you're looking for, a language can become too popular. In this case, you start getting people in the community that detract from it, rather than contribute to it.
The study sounds interesting, though there are obvious risks to trusting self-reports, but I think you're taking a broader meaning of "familiarity" than they're using - I read the result as "programmers are likely to use a language that they know when starting a project" and I don't think you can generalize to "programmers are more likely to use a new language that's similar to a language they know" (apologies if there's something in the video that's not in the text, can't watch videos here). Certainly past a certain point the library ecosystem and pool of familiar programmers become self-sustaining, and I can well believe that such things would be the biggest factors in any given project's choice - but that can't possibly explain how a language gets to that point in the first place.
For many of us the distinguishing characteristic of Java was that it was heavily marketed, often to managers; in the early days it felt like a lot of Java users were doing so under orders. (With 1.5 and the introduction of generics the language became a lot more programmer-friendly and I think at that point it developed a lot more grassroots popularity). Being less cynical I think Java did offer something unique in the form of crossplatform multithreading with a well-defined memory model - it's easy to forget how valuable that seemed, particularly as the world moves away from conventional threading. Possibly the combination of memory-safety and claims of C-like performance was new as well? I'm speculating here as I'm not so familiar with the less popular alternatives, but I think it's not simply a case of Java being less weird or more blue-collar than Self or Modula. The popularity of Python (with weird syntax and modula-like modules) and Javascript (with a Self-like inheritance model) show that that level of weirdness is no barrier if a language has a compelling advantage.
(Likewise Go, I think - it's taking programmers largely from Python/Ruby land where it can claim a USP in the form of performance (while retaining good async support and some level of conciseness). And again, marketing seems to be somewhat involved - so often when I ask "Why did you choose Go over OCaml?" the answer is "What's OCaml?".)
I think the clearest strike against the blue-collar approach is Perl. Perl took an extremely "pragmatic" attitude to language design, adopting many "most bang-for-the-buck features" (deemphasising consistency or underlying coherence), and put a lot of emphasis on tooling and libraries with CPAN, PerlUnit and the like. And for a time it was very successful - but ultimately it became a language that was very hard to evolve, whereas other languages (in particular Python and Ruby) were able to catch up on the tooling side and their coherence gave them an advantage in the long-term. I think Kotlin is making the same... mistake would be too strong a word, Perl is a success story by many measures, but I think Kotlin is taking a very short-term strategy; it feels like every time someone figures out a clever thing you can do with implicits in Scala it gets added to Kotlin as a language feature. Everything about it feels very ad-hoc, particularly in comparison to Ceylon. So I think that while Kotlin may be a very effective language for the short term it's going to be a very brittle one that will struggle to adapt in the future.
I guess that's the closest thing to a counterexample to my original claim - a lot of people did move from Perl to Python with no USP beyond being clearer and smoother. FWIW I think the issues with Perl were deeper than those with Scala; there is some ad-hoc junk in the language (structural types should never have been added, nor should Dynamic, async/await aren't worth it...) but it feels quite peripheral, I think the core still fits together nicely. But hey, if those issues do end up forming enough of a toehold for Ceylon to take over, I'm fine with that too.
You won't find much argument from me here, but I think I need to clarify my point. I'm not saying that blue-collar is "better" or even has better chances for adoption[1] (though I believe it does), but that when you decide to go non-blue-collar, how exactly do you do that? For example, you mention "deemphasising consistency or underlying coherence" as a bad thing. But how bad is it? We know memory safety is important. Do we know sound type systems are important to the same extent? My important meta-point was that when designing a new language for the industry, you should at least do so to solve a problem that you believe (preferably with empirical evidence) causes real pain in the real world. That's how Java, Erlang, Clojure, Rust and even Kotlin were designed (Kotlin is different because it's decided to solve a less-painful problem but for much less cost, but the same thinking is there). Are crude type systems a real problem? I don't know, but I certainly have never seen any evidence to suggest that is the case. So if you set out on this path, at least conduct a survey or research (or even your own rich experience) to convince yourself that your solving a major problem. Why? Because unlike many other tools, new languages are very expensive to adopt. The higher the cost -- the bigger the benefit you must provide.
Having said that, as you correctly note there are other paths to adoption, such as being the only language on a popular platform (JavaScript, Objective-C, Swift), or being a scripting language. Those seem to have their own rules.
[1] Although Java wasn't more marketed than other heavily-marketed alternatives at the time, and Python and JavaScript both have their own peculiar adoption stories, with JavaScript still trying to look similar to its "sister-language" Java, and then being the only choice on a popular platform, and Python taking a long time for decent adoption that even today is far from C/Java/C# levels of popularity, and either case being, or at least starting out as scripting languages for small programs -- not as languages for "serious" systems.
I'm not sure the evidence is any stronger. I mean, you can point to some bugs and say they were caused by a lack of memory safety, I can point to some bugs and say they were due to a poor type system.
Certainly there were problems I faced in day-to-day Java programming that were visibly due to a crude type system - NPEs, the awkwardness of working with checked exceptions (I do think Ceylon has missed a trick by not using union types to interoperate with Java checked exceptions), SQL injection vulnerabilities caused by not having a taint checker. Other problems I recognised as being due to crude typing in retrospect - the fact that missing transaction annotations could failed silently in confusing ways ( http://thecodelesscode.com/case/211 ), the ease of forgetting to close files, the way all the ways of doing async were either invisible or painfully verbose. Ultimately, everything that we resorted to (inherently non refactor-safe) annotations for. (For what it's worth, I originally picked up Scala based on my experience with the JSR308 checkers framework - the functionality was valuable but too many tools didn't interoperate with it properly, so I looked for a language that had the same thing built-in).
Any individual problem from that list you can solve at the language level - some of them have been solved in Java already, and more in the likes of Kotlin. But a powerful type system is a tool that, once it's built into the language, lets you solve them all even if you didn't think of them first. (Macros have the same kind of power, but maintainability of macros is a real problem). I don't think we'll find an example of a powerful type system being better at a specific feature any more than we'd find an example of a generic data structure being better than a specific one; the value comes in being able to do many things the same way.
Making a language that can be evolved effectively is certainly a real problem - again Perl is the clearest example, but I've also heard complaints about how long it's taken Java to implement features that have been agreed on for years (lambdas, modularization). I don't know whether it's the problem King was intending to solve with Ceylon (though I do think Rust represents a very deliberate effort at the same thing) and I don't think it's easy to prove that you have solved it short of waiting a few decades - I certainly don't have any hard evidence about what factors make a language able to evolve in the long run. Nor would it be a compelling marketing story even if you could prove it. But I think it's still worth working on.
I really like your answer. I think it's very important to start with actual problems and then work your way towards a solution rather than vice-versa, because I've always been more troubled by all the bad things people do with rich types[1] rather than notice the importance of problems they do solve. On the other hand, any powerful general tool built into the language can be more trouble than it's worth. Macros are a good examples, but types can be worse. Macros are local to an expression, but types carry the magic with the variable. Sometimes types just carry restrictions, which is OK, but when traits/typeclasses/implicits are involved, they carry actual "bad" magic. So while other specific solutions may take time to implement, codebases live for a long time, so I'd rather wait and suffer some inconvenience, than have people turn a codebase into an unmaintainable, magical mess (which is what I've heard large companies using Scala say it's done to them). Linear types and intersection types are indeed less prone for abuse, and are mostly "restriction-only", so they seem safer, and are less likely to be abused for data types rather than cross-cutting concerns. Another approach -- my favorite -- is exactly Checker. I agree that at this point in time its UX is pretty bad, but it really doesn't have to be. It's mostly a result of the U-of-W putting more effort into the actual mechanics rather than the UX (which, IMO, is a mistake, but they're a university and naturally care more about research...). The Java annotation-processing mechanism generally works very well with IDEs.
Another question is, how bad those problems you mentioned really are. Concurrency bugs are terrible, and simple data typing bugs are usually a non-issue, but tainting/resource-use (i.e. solvable with intersection/linear types respectively) may be bad enough. I really wish someone would conduct an empirical research comprising a taxonomy of bugs, their frequency, and their cost. Such data would be infinitely more useful for language design in the industry than, say, all research going into session types (not trying to pick on session types research, but I hope you catch my meaning when I speak of actual applied utility).
BTW, I think any interesting idea is worth working on. The problem is that a language is a very expensive tool -- and a risky one -- so when it comes to industrial, rather than academic, use a lot of care should be taken when picking one, so it's better to err on the side of caution.
[1]: See Scala's collections as an extreme example. Is it really necessary to go through all that trouble of unreadable code just to save us a cast here and there that has never really bothered anyone?
Hmm, the reason I find types clearer than macros is that they do apply everywhere, so there's consistency across a codebase. <- will always mean a call to flatMap - which might do something different in one place or another, but only in the same way as a normal polymorphic method call - whereas different macros might use it to mean unrelated things. I think IDEs handle them better too - you can refactor in the normal way, you get types on mouseover. Last time I tried to use Checker it was similar - the IDE has good support for running the checkers, but it can't and won't apply the right annotations when extracting a method, or show you the checker-inferred types of local variables.
I do think implicit conversions allow too much; IMO we need typeclasses and extension methods. So my ideal design for a language would include implicit parameters but not implicit conversions, and instead have dedicated support for extension methods. That said we do need to be able to use typeclasses without disrupting method application syntax (i.e. support the use case that means Spray prefers the implicit-conversion-based "magnet pattern" rather than a typeclass).
More generally I think there will be languages that allow too much and languages that ban too much, and we need languages on both sides of the line to allow us to converge on something better. Most places I've worked have had a strong code review/pull request culture which may have coloured my experience - I just haven't seen the Scala maintainability problems you talk about.
(If I thought the complexity of collections was necessary to avoid casts then I would defend it - casts can fail and so it's very nice to have a codebase where they're banned entirely (enforced with wartremover). But I don't think it is - FWIW Odersky's asked for proposals for scala collections in version 3, and I think there's a substantial push towards at least some simplification - perhaps replacing CanBuildFrom with a 1-parameter typeclass that would retain most of the power and simplify the code. The showing-off cases like BitSet#map would require one more method call, but no casts)
> Have they tightened up the floating point semantics? Or do you still get different rounding behaviour on the JVM, dart and JS?
Doing so ought to be trivial if they haven't. Java has a mode where it uses doubles everywhere. JavaScript has Math.fround() for single-precision arithmetic.
:( This is something that would, in itself, direct me to Kotlin or something else. I know that Eclipse is a better fit for Ceylon (because both are intimately related to OSGi), but I really wouldn't want to go back.
I guess for me I don't need nor want JVM + JavaScript VM interoperability. My gut says this limits what can be done. I would rather have just one or the other.
This language looks pretty cool, but I do agree with your gut. The FAQ says:
"Note that not all Ceylon modules are available for both platforms. A module might be cross-platform, it might by JVM-only, or it might be JavaScript-only. Of course, ceylon.language is completely cross-platform."
Having some modules for JVM and some are for JavaScript-only would make things a little bit more confusing than if the language picked one. I haven't decided if this is a very significant thing or not.
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.
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.)
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.)
I hope they'll redo some of the documentation with this upcoming release. Every time I read it, I am amazed by how comprehensive it is but still manages to miss some very important points.
Like the fact that on the main page, the link to the online editor is not under the "Try it out" section. The explore action from that section is also misleading.
Or a clean hello world, with a real project structure documented
Or the way collections are documented. Basically, you have section 6 from the tour of ceylon: Streams, sequences and tuples. But it's not obvious what is the big difference between streams and sequences and the fact that sequences borrow the array notation while being immutable doesn't help either. Even when you go to the List api, which is the interface any Java developer will look for,you can't find the mutable collections, because they live in another module.
This is great, but who is using it? I enjoy learning new languages, but knowing who is using it (and perhaps why) is a good indicator of momentum in my opinion.
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
- 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.
- 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.
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.
"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).
> 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 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.
> 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.
> 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?
> 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.
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.
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.
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.
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.
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.
I looked for example projects in Ceylon with step-by-step info on how to setup/deploy:
* Hello World web application
* Simple online store implementation (authN, database access via ORM layer, logging)
* Todo MVC implementation
* RESTful/XML/SOAP web services
* RESTful/XML/SOAP clients
* Examples for writing AngularJS and React front-ends with Ceylon back-end services, with info on how to host such as to minimize and cache assets and server-side query caching and either side-loading or multi-table joined/extended data structures, updating and reading/accessing those data structures partially.
* Examples for easily timestamping and userstamping models
* Examples for using testing frameworks: unit, integration, (web) acceptance
Also, I'd want to see benchmarks. Show me how much it is "like" performance of equivalent Java, Dart, and JS as is claimed by comparing to maybe a Play Framework app, the Dart example client-server https://www.dartlang.org/server/google-cloud-platform/app-en... , and a simple MEAN stack and/or full-stack example using ReactJS.
In addition to those examples, I'd want to see a larger community behind it with a variety of projects, e.g. specialized ORM, larger web app/services framework, simple web app/service framework each that have their own communities using it.
I think it is cool, but I don't think it is even in the same ballpark with solutions/combinations like Play+Scala, MEAN, Rails, Elixir+Phoenix, etc. for wide application in web/services.
I don't like the extensive use of the ` character, because it's really hard to use on a german keyboard: it get's added twice :( Other than that this looks great!
you might want to look into changing to another keyboard layout. as a swede, using altgr+[7-0] to get (curly)brackets is just ridiculously cumbersome compared to say a us layout.
Scala and Kotlin are mentioned so many times in these comments about Ceylon (42 times and 66, respectively, as I write), but no mentions of dynamic languages Groovy, Jython, or JRuby. I guess that shows there still a clear distinction between languages built from the ground up for building systems, and languages originally built for scripting, build scripts, and testing.
I don't think the distinction is the one you're making it. The original intentions of languages are accidents of history (Java was originally for set-top boxes), and the likes of Python and Ruby are perfectly legitimate languages. The best options on the JVM happen to be typed, but there are good untyped languages and bad typed languages, and parochial typed languages and general-purpose untyped languages too.
Did anybody checkout xtend-lang.org? It's for sure better in terms of Java-interoperability and IDE plugins (Eclipse and IntelliJ)
And it even has macros!!
i want it! it will increase my job security with features like this :
==
String name => firstName + " " + lastName;
And an assignment:
String name = firstName + " " + lastName;
In the first example, the expression is recomputed every time name is evaluated. In the second example, the expression is computed once and the result assigned to name.
==
A function which looks like just a variable and recomputed each time! Happy debugging my code, suckers!
i've been using fat arrows for function definitions in es6, and haven't had a problem. I think the confusion in your code has more to do with poor code than fat arrows.
i think the poster thinks that with the fat arrow definition, name becomes an implicitly called function wherever it is used. I wouldn't like that either.
but, I dont know if thats really the case though (I dont know ceylon). I think that fat arrow line would just become a no op instead, creating a lambda and throwing it away immediately ("name" being the param name in the lambda and nothing more).
I want to like Ceylon because it's the language Scala should be (assuming that higher-kinded types made it in - I could never work without them). It's Scala with all the ugly parts polished away, Scala with ten years' progress in language design.
But it does nothing that Scala can't. Scala might need a pile of bodges to offer these things - Shapeless implicit macros to use tuples generically, type-level libraries abusing the implicit resolution rules to implement unions, a retrofitted JavaScript backend. But that stuff has been written now, and as a developer it works - maybe with a couple of ugly extra lines here and there, but that's all.
I'm glad it exists, but I just can't see people choosing the more polished language over the one with ten years worth of library and tool support when there's no USP beyond that polish.