57 comments

[ 3.6 ms ] story [ 135 ms ] thread
As a fan of both Kotlin and Scala, I'd be interested in hearing if there was more to the decision to migrate away from Kotlin than their existing Scala code base.
I wasn't directly involved in this decision and I've never worked on our mobile apps, but I do work at Lucid. Almost the entire engineering team can write Scala. About 3 people can write Kotlin. That was a big part of it. The lead engineer on our Android app is also a Scala wizard.
Interesting that people feel the need to write posts justifying why they didn't implement in Kotlin.

Says a great deal about Kotlin.

I went the other way, Scala to Kotlin[1], and that's kind of the way I look at it. Scala's a really, really neat experimental language with some awesome ideas, but the amount of work it so frequently entails is disheartening to deal with and the developer experience with Kotlin is so, so much better in both tooling and expectations.

If your stuff is awesome, you don't really have to justify it like this.

[1] - though these days I mostly just write Node with ES6 or TypeScript, because consistency of ecosystem between browser, mobile with React Native, and the backend is just way easier.

My experience with Scala on Android was similar. As a language, it's very pleasant and powerful and would be ideal for Android programming if only you weren't constantly fighting against the fact that Android's tooling and technology were built around Java. It's a time suck. React Native is vastly easier, even though it means using Javascript.
To be honest, I was all-in on "screw JavaScript" until ES6 came around and Babel became stump-dumb-easy to deal with. I've found that just getting things done has gotten a lot easier in modern JS and TypeScript is a powerful tool (though working with React/Redux directly with it is kind of a pain in the ass; I tend to write React components in ES6 just so I don't have to what-the-hell-am-I-doing-with-my-life my way through react-redux).
FWIW, google adopting a second JVM languages means that Android tools will trend toward operating on bytecode and not source where applicable. They released some annotation processors for Room and their lifecycle stuff that operate entirely on bytecode so work well enough with Scala.
That aspect was already true when I was using Scala. Scala code compiles into .class files, and the Android toolchain takes over from there. Theoretically, no issue at all.
Would you say Kotlin is still experimental though? Scala appears to have a 10-year headstart, but time isn't everything.

I use F# and found Scala to be a breath of fresh air after getting sick of Enterprise-y Java, but haven't had the time to venture into Kotlin.

Scala has been around longer, sure--but it's also a bunch of stuff that doesn't really work well together and I'm still not sure that most (not all, by any stretch) Scala programmers really know how to write a program in Scala that's there to be maintained over the long haul. It can be done, but the pull of the super-broad feature set seems so strong that most of the developers I know personally, including me, write code that's awful to read two months down the line because it's dense and featureful and so very clever (note: very, very pejorative; the line about needing to be twice as smart to debug code as you need to be to write it applies here).

Kotlin is literally Java plus sugar. That's all it is. It encourages doing the right thing through stuff you could totally do in Java but nobody does because it's awful to write in Java. And, TBH, for the 90% case that's pretty great. There's no Shapeless in Kotlin--but that's a good thing, because Shapeless encourages developers with skill but no taste to do awful things and inflict them on, say, me. ;)

So, no, Kotlin's not experimental. Because experimental is a mindset, not an alpha/beta release stage.

Seems like you could make the same argument about modern C++ or other kitchen sink languages - lots of features, lots of ways to write unreadable code.

I've worked in Scala for the last 3 years and I've found implicits to be the biggest issue. They're hard to debug, it's not easy to tell which implicits are in scope. Things like that.

Being clever is a problem with the developer and not the language. Scala code is dense, sure, but that's not inherently a bad thing.

I would also say that most people should not write C++. To be clear, I like (Modern) C++ a great deal. I also like Scala a great deal. I don't think most programmers should write it.
I also like C++ a lot, but in what concerns the current OS trends from Apple, Google and Microsoft, even Qt Company, it appears its use is being shifted down the OS layers to pushing pixels, audio frames and driver data around.

With everything else built on top of it with safer languages.

This is quite clear with the set of APIs that are being made available to C++ on those OSes.

Yea, implicits were definitely confusing at first. That and picking a thread pool required a lot of reading. There seemed to be some other outset issues like "avoid this seemingly innocuous operation since it actually has a huge perf hit", but those usually manifest quickly and get eliminated with any sort of application tuning.
This is so very true. I find Scala tends toward the classic "read-only" joke. You can write very powerful code, but it's often hard to debug and it tends to be quite difficult to read down the line. We have a Scala application that is being slowly replaced, but which I maintain in the meantime, and it is by far my least favorite job duty, despite that I theoretically like Scala more than, say, Java.

Probably my biggest disappointment with Scala is really the type system. It's incredibly powerful, but it's unwieldy to use, and it's still full of footguns. "object" is great and useful until someone accidentally turns it into a giant race condition (true story). Traits can easily turn into a maintenance nightmare (ever seen an 8-way multiple inheritance scheme that fans out into 23 separate ancestor classes? I have!) Exceptions end up in a strange territory. There's ways to handle all of this (much of it involves "don't do that!"), but the point is that for all the type system's powers, it's not actually buying you that much except in comparison to Java 6/7. If I want powerful type magic, I can use Rust or Haskell or similar and get stronger guarantees from my compiler. If you're writing "better Java", which is traditionally one of the more common Scala uses, it's harder to justify over Java 8 or Kotlin these days.

All of which is to say, Scala is a really cool language, but I wouldn't write new projects in it if I didn't have to.

Bonus round: We had a Scala iOS app via RoboVM before RoboVM support was yanked. It still gives me nightmares.

Yeah, all that pretty much tracks for me. I think the best way I've heard it described is thus: you can write Perl in any language, but it's really hard to write Scala in anything else.

I wrote an Android Scala app once. I regret the experience.

So is React Native a truly viable way to build a complete mobile application?

Any downsides, weak areas, problems?

Well..."truly viable" means different things to different people. I'm a devops jock (so build systems never really scare me, and that's probably the nastiest part of React Native) but my background is in application development and I got up to speed with React earlier this year. I built in five days a well-scoped but nontrivial app I'm releasing as soon as I get my LLC and EIN situation figured out (I might Show HN it) and I'm extremely happy with the result. The app works as-promised on Android and iOS; I have some additional stuff to do before I launch the iOS version because theming isn't 100% between iOS and Android, but it was recognizable and usable from the jump and it by-and-large worked as intended.

The downsides are mostly what you'd expect. You're welding together a JS bundle with Java (Android) and Obj-C (iOS) generated projects to create a deployable and that's a little fragile, though it's not really a problem. `react-native link` exists to try to help with that by automating the insertion of dependencies that require going outside of JS (stuff like Firebase or other native-API integrations); on one hand, I've never gotten it to work, but on the other, I know both Android and iOS development separate from React Native so it's totally not something I even think about. That probably also encapsulates most bugs I might run into with packaging, etc. to the degree that it's really hard for me to answer your question. I already know both of those environments and most of how they get wacky; stacking a little on top of that's not really a big deal.

The hardest single thing to do was integrating Firebase because I got some wacky Gradle error, but I figured it out. The second-hardest thing was parsing every JS package (460 packages, yeeesh) in my app so I could make sure I included their licenses in the deployable to be compliant with the licenses (and I am certain some of the licenses I included are actually from the build tools, but whatever). There are 500kB of licenses in my app, hidden in an 'about' dialog box that I expect nobody will ever open, but if that's as hard as it gets...meh.

Debugging is worse than it could be, but it's React/Redux in a very constrained environment, I'm not worried by it. And there are often no platform-agnostic wrappers for stuff (I needed in-app billing as my app is time-limited demoware, and I have two separate codepaths), but let's be real--that's not much of a thing.

I like it. React and Redux are comfortable ways to handle state management and I don't spend much time thinking about it. It means not writing Java or dealing with Android directly and iOS development is certainly no worse, and probably a good bit better, than it was before. It's faster to make something that looks and feels good. Also, and it's a little thing, but the react-native project creation tools are awesome and they make getting off the ground really easy.

The "interesting" part about the article is Scala vs Java more than Scala vs Kotlin, since Scala is generally accepted as a horrible match for Android from compilation times, to method counts, to binary sizes, to performance.

This post is essentially someone arguing how their choice with no benefit to anyone but the developers of the app and with drawbacks for all other stakeholders (since finding quality Android devs with quality Scala skills will be hard and product quality suffers for the reasons I mentioned above) made sense because they already wrote microservices in Scala, ignoring the fact that Android has a very specific set of challenges and development methods that make it's similarity to "normal Java" superficial at best, let alone Scala.

To top it off, the article is touting several things that even normal Java Android development can do:

TypedResource and TypedViewHolder = Databinding, But I prefer Butterknife anyways

Replacing AsyncTask = Really dozens of ways, there are Futures in Java, I'd go with RxJava (and Retrolambda) personally.

case classes = AutoValue (but I'll admit case classes are more concise)

It's also ignoring things like how much of the syntactical sugar shown increases method counts.

> compilation times, to method counts, to binary sizes, to performance

besides compile times (mitigated almost entirely by incremental compilation) none of these things hold up. Method counts are irrelevant with proguard and multi-dex (FWIW, most of our count comes from google support libraries anyway). Our binary is around ~5mb. I haven't ran benchmarks but I promise you that http requests, writing to disk, and WebView performance aren't slower because of Scala.

So you're saying the app is so small and extremely simple that even at full load jank isn't an issue, that multidex and size aren't an issue because you're not forced to focus on startup times and there are hardly any assets.

And I'm not saying that skeptically, I really believe it. Which is all the more reason that I don't see why you'd go with the using Scala. I don't know if you're referring to Lucidchart but I just look at that app and I can definitely see how it might not have to worry about jumping through hoops to shave startup time from a high method count or loading large data sets with tons of serialization and performant animations where built in immutable collections have unacceptable GC implications.

On the other hand you can apply that same reasoning and say it doesn't matter that Scala was used. But then you wonder why the "case study" should be considered by others, who probably don't have the luxury of having a small minimally animated app that can ignore stuff like method count effects on startup speed. To me the things that separate a top 50% app from a top 1% are things like high method counts affecting startup time on slower devices. It's not like Kotlin doesn't have issues that mirror those in Scala, but because it's essentially a "thin wrapper Java" with a slim standard library it's easy enough to identify when you're going to run up against parts with those performance implications

(comment deleted)
> no benefit to anyone but the developers of the app

So? Benefiting developers is very important.Development cost is the highest cost of software. Even if the only benefit of using scala is higher developer morale and productivity, it could very well be worth it.

> finding quality Android devs with quality Scala skills will be hard

We already use scala heavily at Lucid. We have to train Android developers in scala anyways. For us, using scala means the android developers only have to use one language, instead of two. It also makes it easier to leverage some common code in both the backend and the android app (for example serializing/deserializing objects over the network).

Using scala to write an android app isn't the right choice for everyone, and I don't think the OP is suggesting it is. But it was the right choice for us. And if you are already using scala in production, it is certainly something to consider when writing your android app.

I'm a heavy Scala user who is somewhat skeptical of Kotlin, so you might say this article is preaching to the choir.

And yet...while I'm convinced that it's quite possible to write Android in Scala, but I don't understand why the author's team chose Scala over Kotlin for their Android app. I presume that there are benefits to being able to do front-end and back-end work in the same language, but is this of interest to devs that don't already have a lot invested in the Scala ecosystem?

I don't see any real justification here for why it was worth the effort to port the code from Kotlin/Java to Scala other than reusing their "well-established skills with Scala" and "using sbt for our Android app has also allowed us to leverage our unified build system". They're both valid reasons, but they're not so much technical decisions as pragmatic ones for that particular company.

The post states "hopefully I will be able to illustrate how Scala can dramatically improve your experience while developing Android applications". This claim isn't addressed in the post at all however. For example, it states "Scala has a pretty decent concurrency primitive in Future" and explains how to use them, but doesn't say what they offer over and above Java futures or Kotlin coroutines. Most of the post is talking about how they migrated their codebase and any compatibility or technical hurdles that were overcame on the way (e.g. the sbt/Gradle mismatch), not about why Scala was a better choice technically or what benefits it offers over Java or Kotlin. There's no mention either of other practical issues such as the large standard library, method counts, compile times and so on.

The addition of a few strong comparisons would be welcomed. As it stands, the post feels more like "please don't fire me" than "where's my promotion?".

> As it stands, the post feels more like "please don't fire me" than "where's my promotion?".

Couldn't help but notice that sentiment in the passive wording of the title: "don't regret moving" is not exactly a ringing, jubilant endorsement.

I got the same vibe. Sort of a "hey, it actually wasn't that big of a mistake".

I didn't get the feeling they'd do it a second time if they had a chance to do it over, knowing that Kotlin was about to get official support. (Or then again, maybe they just really love writing Android code in experimental, unsupported languages! And if so, who am I to judge?)

Well we also used Swift way before a "stable" release came out. So maybe we're masochists.
I think a more apropriate title would have been "How we migrated our android app from kotlin to scala." There is a little talk about the benefits of using scala instead of kotlin, but that isn't the bulk of the post. I would be interested to see more of a cost-benefit analysis of the decision to migrate to scala, and the outcome.
> Getters

> Scala generates public getters for all public member

God what a sad, sorry existence you must live to be writing about "getters" in 2017. Java programmers and their descendants are the true Luddites of the programming world.

While I don't agree with the general tone of the above comment, I am curious if anyone can enlighten me on why one would need a getter on a member that's already public.
you don't. Scala produces them automatically for case classes. Kotlin will treat x.count as x.getCount() if getCount exists and count doesn't. They are mostly a side effect of the tools and not strictly required.

Especially in Kotlin and Scala where data tends to be immutable by default there isn't much to gain by using getters.

If your "getter" is doing more than getting the value then maybe you should not call it a getter (imo).

> If your "getter" is doing more than getting the value then maybe you should not call it a getter (imo)

I'd definitely agree there! In fact, I might go further and say that if your "getter" does more than just return a member, then by definition it isn't a getter

I think the heart of the question was more, if the members are already public, why does Scala need to produce getters for them, why not access the members directly?
I forget who said it, but there's a quote along the lines of, "There's no problem in programming that can't be solved by adding another layer of indirection. Getters are just that, a layer of indirection. So they give you a hook to intercept a call and do something that wouldn't be possible with direct field access. Perhaps you want to lazy-load the field, or dynamically compute its value under certain circumstances. Whatever it is, if you use getters from the outset, you won't have to change code that calls the getters when you decide you need that indirection.
Fair enough, although those types of things seem like they'd need to be explicitly written, not auto-generated by a compiler (like the ones described as existing for Scala)
That's the whole point of what Scala is doing.

Allow flexibility to support such requirements later on, without forcing people to break source and binary compatibility, unlike in Java, C# etc.

That's the reason why you can e. g. implement or override a def with a val.

One thing I've noticed with Scala is Scala devs love rewriting everything in Scala. Now, on one hand I totally get it, rewrites are fun and when you're coming from Java and get used to Scala you never want to write any more Java. (Especially at the time when Scala was really exciting and Java people were in Java 6-7 period.)

The Scala ecosystem reflects this. There's integration with Java classes, but calling Scala code from Java is less good. There's no binary compatibility between major Scala releases. Scala has its own "simple" build tool.

I'm impressed the article's author was able to build their Android app in Scala. However, I would not recommend using Scala on Android. No doubt Android is popular in part because of Java, but the entire ecosystem is so much more than the programming language.

The sbt-android plugin mentioned may work, but will never have the feature set of Gradle integration. (Building Android applications is much more complicated than a regular JVM app.) . In addition, sbt-android doesn't allow you to use Android Studio, which is also a huge handicap.

Compatibility is likely an issue (Scala 2.12 requires Java 8, and support for Java 8 bytecode has only been introduced in O). Compile times, memory usage, method counts, etc. are all hard problems Android developers must be aware of that are blissfully ignored by the Scala team.

By the way, all of this is why Android developers love Kotlin. As it was designed for complete interoperability with Java, Android devs can migrate piecemeal. You can use the same libraries, the same build system, the same IDE. The reason why the biggest announcement at Google IO was Kotlin support was because Android devs were already using the language and seeing its benefits.

> sbt-android doesn't allow you to use Android Studio, which is also a huge handicap.

Some of our team uses Intellij, some use Android Studio to do Android dev. Both work fine with sbt-android.

> You can use the same libraries, the same build system, the same IDE.

This is true of Scala as well. Granted the gradle scala plugin is not great (though it does seem much better than when I last looked at it). sbt-android-gradle lets you use gradle and sbt side by side for android apps. For a while my team used this.

> The sbt-android plugin mentioned may work, but will never have the feature set of Gradle integration.

I'm curious if you know of any of these features sbt-android is currently misisng. I believe some of the new Android O font stuff might not work yet. Instant Run might be the next thing to be mentioned but it's replaced really well by sbt-android-protify.

> Scala 2.12 requires Java 8, and support for Java 8 bytecode has only been introduced in O

This is (imo) the worst part about all of this. Even Android O isn't the full java 8 bytecode so scala 2.12 still doesn't work.

> all of this is why Android developers love Kotlin

Yeah, I think Kotlin is a godsend for Android. One thing I don't think I mentioned in my original post was that Scala benefits from Google's kotlin support as well. It means many tools google produces (new arch components come to mind) operate on bytecode instead of source. So they (more or less) automatically work for scala too.

Certainly kotlin was thought of from the ground up as an Android language and it shows.

You also mention method counts a few times. I admit this is somewhat of a problem but it's also worth pointing out that sbt-android runs proguard automatically for you during release builds. We haven't come close to 65k (with or without proguard) and 70% of our method count comes from android support libraries published by google not the standard library methods provided by scala. We also target api 21 so multi-dex is not really the headache for us that it used to be.

> As it was designed for complete interoperability with Java, Android devs can migrate piecemeal. You can use the same libraries, the same build system, the same IDE.

This is all true for Scala as well.

Not really, it appears to require InteliJ and cannot work with the modified version that is actually Android Studio.

It also doesn't integrate with the language aware tooling from Android Studio or the Gradle versions being used on Android Studio.

At least this was the situation last year.

No, it's not. Scala can call Java easily, but not the other way around. Calling Java from Scala is awkward at best (in many cases) and sometimes impossible. Scala was never engineered with a smooth Java/Scala mixed mode in mind. The opposite is true: In Scala almost everything from Java gets reinvented sooner or later.
This hasn't matched my experience.

> Calling Java from Scala is awkward at best (in many cases) and sometimes impossible. Scala was never engineered with a smooth Java/Scala mixed mode in mind.

I assume you meant calling Scala from Java here. With that in mind, writing an API that is easy to use from Java isn't that difficult. It is basically down to limiting the feature set you make use of in the interface and converting to Java collections. These are both pretty easy to do. Granted some Scala features are expressed in ways that are not easily used from Java. However, this just because Scala is significantly more expressive than Java. I'm not sure why you consider this to be a problem.

> In Scala almost everything from Java gets reinvented sooner or later.

I'm not sure what your point is with this. Scala wrappers for Java code are common but not because of issues with calling Java code. These are written because Scala can expose a much richer and much safer interface (again because Scala is much more expressive).

This just smells like poor underlying technical leadership more than a success story.

Considering kotlin has really only recently become a 'mature' choice (if it even is) to have a app written in it seems unnecessary but to then rewrite a production app like for like because that language wasn't even a core competency of your business in the first place is just reckless.

Technical debt is a luxury small business cannot afford because of the opportunity cost of seeing it as technical debt.

Technical debt is usually taken in exchange for speed of development. It's exactly what a startup does.

A mature company can pay out all its technical debt, iron out the kinks in the tech stack and polish well-working solutions. Until the business requires another prompt and unexpected change, of course.

> A mature company can pay out all its technical debt, iron out the kinks in the tech stack and polish well-working solutions.

Sorry, Hacker News is a place for serious discussion, not absurd jokes.

I've seen certain core systems being polished for years, removing the bulk of the local technical debt.

Having zero technical debt company-wide is unattainable and impractical, though.

I like Scala, but the fact that Kotlin is officially supported makes it seem pretty compelling for an Android app.
Come on, this is neat. Try to appreciate it for what it is, a company investing in Scala on Android. Who cares if Scala is not the idea Android platform. There was a guy who was live-coding on iOS in Scheme a long time ago and I don't remember everybody shitting on him. People are using Clojure for Android even though it's not necessarily a great idea. If my only choices were Java or Kotlin I'd probably shoot myself, but I'm not an Android dev.
If that guy released the work as a production app then wrote an article trying to sell us on the process, people might react a little more strongly.

There's nothing wrong with doing interesting things, but you need to be clear to yourself and others that it's being done because it's interesting, or for a specific reason other than "it's a generally good idea"

They state the reasons in the article. You may disagree with them but they seem reasonable to me.
No one is saying they're unreasonable, some people are disagreeing with them. But you're strongly implying disgreeing is "shitting on them".
The claim is modest: I don't regret the decision. Disagreement in this thread is mostly piling on, one commenter says 'the post feels more like "please don't fire me"'. The disagreement is that "the author should regret it" which is pretty distasteful.
Looking forward to: Why I moved back form scala and you schould too.