I don’t want to go into in-depth analysis of Ceylon and why it had not gained much traction here. I personally think that Ceylon union types are its weakness, not its strength. Idiomatic Ceylon code that uses union types becomes alien to Java code because Ceylon’s union types get exposed as
Object in Java. On the other hand, Kotlin design had carefully avoided (and even actively dropped in pre-1.0 times) decisions that made it hard to mix code in two languages. The goal was to make sure that Kotlin and Java ecosystems can co-exist naturally even side-by-side in the same project, so that idiomatic Kotlin code is natural for Java code aroud it and vise versa. I don’t know how much that particular thing had affected popularity of Kotlin vs Ceylon, but it does make a difference.