Hacker News new | ask | show | jobs
by Nycto 3383 days ago
I'm a huge fan of Kotlin. I think the author just doesn't understand the niche it hits.

My team has a significant investment in the JVM. I despise working in Java because of how heavy it is to write. I like Scala, but the team I'm on finds it too complicated. Clojure is out because nobody on the team wants to write lisp. And Groovy doesn't have types. We looked at Ceylon, too, but at the time we hit a lot of compiler issues (if I remember correctly).

So where does that leave us? There are likely other languages we could choose that target the JVM, but the pragmatist in me says I don't want to stray too far off the beaten path for this.

Is Kotlin perfect? No. But is it a better developer experience than Java? Oh hell yes.

2 comments

For what it's worth, Groovy does have types. It is not dynamically typed, but optionally typed. Throw a @CompileStatic annotation on your classes (or use a global withConfig) and it is very nicely typed, using Java's type system.
> Throw a @CompileStatic annotation on your classes

Only if your site has upgraded to version 2.x of Apache Groovy, which many sites haven't. Even then, converting everything to @CompileStatic at once only works wholesale for tiny codebases. You'll face a lot of debugging for anything larger -- it's more like "throw" a @CompileStatic onto one class at a time, and test after each. You'll hit the wall soon enough. Consider why Groovy itself is still written in Java, not in statically compiled Groovy, and there's certainly no mention of converting its codebase anytime soon in the latest roadmap posted on their developers mailing list a day ago.

And of course Groovy, unlike Kotlin, only triggers IntelliJ's (and Android Studio's) code completion perhaps 80% of the time. Kotlin was created by the same people who built IntelliJ and for the explicit purpose of working properly with it 100% of the time.

What did you struggle with in Scala? Anything you could write in Kotlin you can write in Scala with the same structure. Scala has some extra constructs that can save you a lot of code a lot of the time, but you don't have to use them if you don't want to. There are horribly incomprehensible libraries available in Scala and there aren't any for Kotlin yet, but I think that's just a function of the fact that Kotlin's so much less mature all-round, and again you don't have to use them.
The "just don't use those parts of language" argument was also used a lot for C++. I just don't buy it.

You are not in sole control of your code base. You share it with your colleagues who are on different skill levels. You are drawn into community gathered around the language and you need to use, debug, and sometimes contribute to other people's code. Just fencing off some common language features isn't going to cut it. It's better to select tools that are well suited to problem at hand, at right level of abstraction and of manageable complexity to your team. Even if that means less features and more ground work.

I agree with you as far as C++ goes. I think the difference is that the things Scala adds respect the rest of the rules of the language.

If you introduce exceptions in C++, everyone working on any line of the codebase needs to understand exception-safety. If you introduce RAII you have to enforce it on every constructor, and since constructors can fail you have to introduce exceptions. If you introduce templates you have to use RAII for all your types in case they're used in a template.

In Scala if you use a higher-kinded type it works exactly as you'd expect (indeed I'd argue that the absence of higher-kinded types is equally confusing - why can't I use List as a type parameter in Kotlin?) - a method or type that uses HKT acts like any other method or type. If you have a function whose implementation uses a pattern match it might make it confusing to read that function, but to any caller from outside that function still conforms to its signature and still makes sense. If your colleague writes a Profunctor instance for one of their types and litters your code with ^>> calls that's probably annoying (and should probably fail code review), but ultimately it's just a plain old function call that you can click through to in your IDE and see what it's doing and whether it makes sense.

I hear you.

In my experience with quite a few Scala project with mixed teams it's not a problem though.

You just maintain some shared culture of "don't do X if not absolutely necessary". You need that for any language. In this case it's: don't do typelevel tricks if you can help it. And it turns out that 99.9 % of non-framework code doesn't need it. And the large majority of devs are fine with writing clear code.

Then there are some smart devs that are at a stage of personal development where they are intrigued with typelevel tricks. I've only had one colleague who didn't wasn't open to the "hey, that's not really necessary there. Let's not add complexity if we can help it" type of code review comment.

To each his own. But for the teams I've worked with Scala was the typed-FP-on-the-JVM lets-get-shit-done language.

Don't confuse the argument of "you don't have to use language features you don't understand" with "certain language features are heavily restricted, if not verboten, in many organizations'/projects' style guidelines." Certainly, many programmers don't understand variance, type classes, and other language tools Scala either has direct support for or is powerful enough to implement and use in a simple and clean fashion. Those advanced tools are often used to reject errors at compile time rather than run time and implement certain types of optimizations without sacrificing safety, code maintainability, or legibility.

Again, using Scala's advanced features isn't akin to something like using raw pointers in C++. I find Scala's collection library a good example of that - programmers of all levels can use Scala collections without understanding all the type-level tech they're implemented with.

> I find Scala's collection library a good example of that - programmers of all levels can use Scala collections without understanding all the type-level tech they're implemented with.

That was my reason to dislike Scala. It doesn't work for me. I must be able to dig into any library code I use. And when I tried to dig into Scala collections library, I ran away screaming in horror. When I tried to implement my own collection based on linked list, I wasn't able to do it. I was able to learn Java collections easily, they are really easy to use and understand. You just open Collection.java, List.java, ArrayList.java and read it, it's easy. It might be hard for something like ConcurrentSkipList, but this structure is hard, it's okay. But when I tried to read Scala's collection in the same way, I drown in traits.

May be there are people who can use libraries purely from interface and documentation perspective. I'm implementation guy, when I have a question, first thing I'm doing is investigating implementation code. And if implementation details are buried below kilometers of abstraction, I don't like it.

The Scala collections library has a fair bit of second-system effect and plain bad design. It's being rewritten with simplification as an explicit goal (even at the cost of sacrificing some expressiveness) for the next major version of Scala. In the meantime there are a couple of alternative libraries, and fundamentally the standard one does work. (If you need to implement a custom collection the recommendation is to only implement an interface - or maybe even just a suitable typeclass - and not try and reuse any implementation traits/base classes from the standard library).

Which is to say, I don't blame you, but FWIW collections are a known-bad part of the language and exemplify a lot of what the community wants to move away from. I find Scala is great for being able to read the implementation of things, particularly in terms of how much the frameworks tend to be written in plain old Scala code rather than magic annotations or what have you (e.g. in Spray/akka-http, all the directives you use to define your web routes are just ordinary Scala functions and you can click through and read their definitions).

I like Scala. I've written a lot of Scala. But choosing a language is a team decision. And Scala draws the same kind of ire as C++. It's to the point that I have seen seasoned engineers laugh any time Scala is suggested.

To provide a bit more depth, a large number of the developers I work with (folks I respect) don't _want_ the kitchen sink. They see it as dangerous. Even if _they_ can handle it, they know that there are a lot of people who can't. Sure, you can limit the features you use via convention, but that is shifting a tech problem to being a people problem -- you usually want to go the other direction.

You can "yeah, but..." all you want, but it's a valid, reasonable opinion. It's subjective, but that's just the way of it.

I was part of a startup where I wrote all our server stuff in Scala. It was just three of us to start and I was the only dev. As we added more people, no one wanted to touch the Scala code.

I tried everything. I made some nice Java interfaces so they could write plugins; exposed all the data they needed, wrote a bunch of documentation, had a learning session. No one contributed a damn thing.

They started firing people after I had already left for Australia and was working remotely. They kept me on while secretly having a former Amazon person rewrite my entire service in Java. Good thing I explicitly asked for the whole thing to be kept GPL prior to the contract.

Last year I got hired into a team that does the majority of their work in Scala. It's been a great experience.

> I think that's just a function of the fact that Kotlin's so much less mature all-round

You mean "old", not "mature". Scala is old and still pretty immature for its age

The Kotlin tooling and IDE support is certainly already way ahead of Scala's after just a year in existence in robustness and functionalities. And I'd rank the two compilers at about the same level in terms of maturity (Kotlin's is much faster than Scala's though).