Why I Don’t Regret Moving Our Android App to Scala
lucidchart.com
lucidchart.com
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?".
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 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?)
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.
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.
This is all true for Scala as well.
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.
[1] https://groups.google.com/forum/#!topic/scala-on-android/0y1...
> 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).
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.
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.
Sorry, Hacker News is a place for serious discussion, not absurd jokes.
Having zero technical debt company-wide is unattainable and impractical, though.
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"
Says a great deal about Kotlin.
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.
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.
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
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.
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.
Any downsides, weak areas, problems?
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.
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.
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.
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.
I wrote an Android Scala app once. I regret the experience.
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.
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.
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?