Was it compilation speed? Corporate support?
Was it compilation speed? Corporate support?
Scala brings its own huge library with features that I don't need. Billions of abstract collections, but all I need is HashMap and ArrayList. They generalize over builders, so `filter` can return some fancy underlying class, but all I need for filter is to return ArrayList or lazy sequence. Kotlin again hits sweet point: all it does is extending standard Java library with few utility methods and it adds lazy sequence type (interface with one method).
Due to Scala huge library it's hard to use on Android with its artificial 65k method restriction. Kotlin doesn't have this problem.
Last time I checked, Intelij Idea wasn't able to parse even standard Scala library without errors. May be it's better now, but my experience is that Kotlin beta plugin was better than Scala plugin. Doesn't relate to language directly, but complexity of the language is definitely influences tooling: simplest language Go has awesome tooling.
Compilation time was never an issue for me, but I guess for some projects it matters.
I don't care about corporate support, but I do care about dogfunding. I didn't see Hibernate being rewritten with Ceylon. But Jetbrains use their own language for their tasks, that means that they are unlikely to abandon it. Google support probably matters a lot for Android developers as well.
That said, Scala is mature language and I don't see it going anywhere soon. It has very rich set of features, it allows much better abstractions than Kotlin, it has huge projects, a lot of developers work as Scala developers. But Kotlin definitely has a momentum.
Would you mind elaborating on what those Java pain points are that Kotlin smoothes over?
Also are people deploying Kotlin on the server side or do you see that being a thing in the future? For some reason I have this(perhaps incorrect) association Kotlin only in the context of Android. But maybe that's incorrect?
1. Explicit semantics for nullable variables. It helps to convey information whether this function can accept or return null and compiler checks that your code won't throw NullPointerException. It's not ideal when you're dealing with Java code, but it works.
2. Explicit and convenient semantics for mutable and immutable variables. You can use `final` in Java for variables or parameters, but few people do that, because code becomes quite verbose. With Kotlin you are using `val` or `var`, so code doesn't become more verbose.
3. Almost everything is an expression. Helps to write concise code sometimes and makes a language more consistent.
4. Compiler changes type of variable when developer checks for this type. So you don't have to write nonsense like `if (a instanceof String) f((String) a)`, instead you write `if (a is String) f(a)`.
5. Better replacement for `switch` statement. Kotlin's `when` statement has more features. Not a proper pattern-matching, though.
6. Default values for function parameters. With Java you have to write lot of function overloads with slightly different set of parameters and delegate it to a single function. With Kotlin you're writing one function with optional parameters.
7. Named arguments. Sometimes it leads to much more readable code.
8. Generic parameters can be covariant or contravariant. Basically you can assign `List<Integer>` to variable of type `List<Number>`. It helps sometimes.
9. Operator overloading. `a + b` instead of `a.plus(b)`; `m["x"]` instead of `m.get("x")`. Code looks much more natural, when used appropriately.
10. Singletons. Kotlin doesn't have static classes, instead it has `object`s, which are implementation of singleton pattern. They can implement interfaces, for example.
11. Proper properties. getter/setters generated automatically, property access looks like field access, but with all perks the methods have.
12. No need for artificial utility classes, which are not really a classes, but just a bunch of static methods. You can either use plain functions at top-level or enhance existing classes with utility methods. `str.isBlank()` instead of `StringUtils.isBlank(str)`, for example.
Generally Kotlin is much less verbose than Java, but it's concise enough and doesn't try to be implicit or magical.
> Also are people deploying Kotlin on the server side or do you see that being a thing in the future? For some reason I have this(perhaps incorrect) association Kotlin only in the context of Android. But maybe that's incorrect?
According to Kotlin developers their user base was roughly 50% : 50% between server side and Android. I used Kotlin for small server side projects, it works almost flawlessly with standard Java frameworks like Spring or Hibernate.
Kotlin is a much simpler language than Scala.
As such it turned out to be a natural fit for Android apps as well, because the platform has pretty much the same type of limitations.
Other nice things: - Standard library is tiny so you don't get a large app size and method count hit. - The datastructures are fully interoperable with Java ones so calling out to existing Java libraries and code feels completely natural. I need to stress how important this is - you can just drop Kotlin classes into existing codebase and things will just work and look natural. - The language itself it very easy to pick up - it fixes A LOT of Java pain points, but it doesn't really try to change fundamental paradigms. Which means that pretty much any Java developer can quickly become productive in it. - The IDE support it superb and practically on the same level as Java. - The compiler is fast enough and good enough.
What are the pain points it fixes?
The article shows google search traffic for Kotlin which temporarily spiked above Scala in the wake of the Android announcement and then dropped back down to less than half the Scala traffic, below Groovy in fact. I'm not sure that it's much of an indicator of anything.
Also of interest:
I would be attracted to Kotlin because IDE (Intellij) verification is very slow in Scala, compilation speed is and will be slow (really interested in efforts to reduce language scope to speed up mentioned on HN earlier), error messages in Scala are a pain.
Would wish for that attitude:
If you look at the graph in the post, it didn't; Scala is substantially more popular. Kotlin is just at a different point in the hype cycle.
(There's plenty I don't like about Scala qua Scala, but I don't see it ever being displaced by a language that lacks HKT. Kotlin has some good aspects to its design, but the anti-intellectual hostility to good formalisms and refusal to learn anything from Scala's mistakes rubs me the wrong way)
They make it much easier to fulfil business requirements in a clear, maintainable way (and mean there's a huge space of libraries available to help with that), which is what programming is all about.
> I like how Clojure works much more (you can opt-in to any extra features Clojure has to offer and they are not forced on you) compared to Scala.
What exactly is "forced on you" in Scala?
> Clojure is a clean language with a very powerful and useful philosophy behind it, Scala on the other hand has a lot of tacked-on features and the whole language lacks consistency and philosophy
Clojure has a clean design as far as it goes, but the design is so spare that to do anything practical in it relies heavily on macros. That's a legitimate language design philosophy and I'm glad there are languages that pursue it, but I don't find it makes for maintainability in the long run; macros are too powerful to be able to reason about code that uses them, so for a maintainable codebase your macros need to be restricted to a subset of what's possible - and to be able to maintain that it would be better to standardize more restricted alternatives that cover the important use cases.
What Scala features would you say are tacked-on? I find it very coherent, with just a few powerful, orthogonal features - it's not quite as minimal as Clojure, sure, but it feels like it's got a lot fewer special cases than Kotlin or any number of modern languages. The libraries some people have written are a lot more... variable, but that's not a sign of issues with the language - if anything it's the opposite.
Same stands for dsls, macros, multimethods, I can mean any feature in any language. HKTs are just one tool of many.
> What exactly is "forced on you" in Scala?
Any built-in language feature. For example no matter what I do `implicit` will be a reserved keyword and the language will make use of it. I can't opt out. In Clojure on the other hand there is [spec](https://clojure.org/guides/spec) for example. If I want it I import it and all of its features are defined in terms of Clojure itself. The whole language feature is a library. I can add [the language itself](https://mvnrepository.com/artifact/org.clojure/clojure/1.8.0) as a library to my project (which is what I do with Kotlin) and use all of its features like the STM, or persistent data structures. Can you do the same with scala? I doubt it.
> Clojure has a clean design as far as it goes, but the design is so spare that to do anything practical in it relies heavily on macros. [...] macros are too powerful to be able to reason about code that uses them
That's why Clojure has spec. It solves the reasoning problem. It is also incorrect to assume that you can't do anything practical without macros, it is quite the opposite. You can do anything without them but there are some special cases where macros are useful. You can read any lisp textbook and you will see this in every one of them. If you write any lisp code then you have to know that for your first few projects you will overuse them, then you might learn where they are really applicable.
Name some special cases in Kotlin which are problematic. I can't name a single one from the top off my head despite the fact that I use the language for more than a year.
Would you say those features have no business value then? I've met enough business problems that were best modelled with HKT that I don't believe a language without an equivalent feature could be as effective.
> Any built-in language feature. For example no matter what I do `implicit` will be a reserved keyword and the language will make use of it. I can't opt out.
Almost all languages have some keywords. But yeah, implicit is a language-level feature. It's got a very high power-to-weight ratio though; it has valuable use cases (typeclasses, extension methods, the magnet pattern) that couldn't otherwise be done in plain old code, unless all those things were their own language-level features.
> In Clojure on the other hand there is [spec](https://clojure.org/guides/spec) for example. If I want it I import it and all of its features are defined in terms of Clojure itself. The whole language feature is a library. I can add [the language itself](https://mvnrepository.com/artifact/org.clojure/clojure/1.8.0) as a library to my project (which is what I do with Kotlin) and use all of its features like the STM, or persistent data structures. Can you do the same with scala? I doubt it.
Plenty of Scala things are libraries, you absolutely can import the scala standard library and use its collections, its async implementation or the like from another JVM language (though they may not be terribly idiomatic there). I don't really see the distinction you're drawing?
> Name some special cases in Kotlin which are problematic. I can't name a single one from the top off my head despite the fact that I use the language for more than a year.
Nullable types are a special case that doesn't compose properly (null is expected to be used for errors but if you write generic code that does that and then one of the values you pass in is null then you've got a bug), and a special case in the syntax (can't write your own type that allows ?. if you want to e.g. include a reason-for-failure message). Platform types for Java interop are a special case (you can't always pull out repeated calls to a Java method into a utility method without changing the meaning). Extension methods are a special case (can't use them to implement an interface). Operators are a special case (can't have an interface that requires them).
But nobody was seriously using it at scale until it stabilised, which was the start of last year.
Judged from its 1.0 "ok you can use this now" release, it's a little under 2 years old.