Scala Native Next Steps

(The Scala Center team is dedicated to providing regular and transparent community updates about project plans & progress. In this forum we created a new topic category to allow quicker orientation going forward: “Scala Center Updates”. Even though all feedback is welcome, we keep the right to make executive decisions about projects we lead. Overview of all our activities can always be found at https://scala.epfl.ch/records.html)

Dear Scala contributors,

The Scala Center is happy to announce the road-map for Scala Native.

Scala Native (SN) was adopted by the Scala Center about three months ago. During this period, we have taken a good look into the project and its prospects. In this post, we would like to share our findings and why we decided to continue our investment in the Scala Native project.

Importance of Scala Native

Scala Native is interesting, because, as its description says, it is “Scala on bare metal”. This means that you can write your program in Scala and get an output that does not have the overhead of the JVM.

More importantly:

  • Scala Native is a Scala platform that can interoperate with native C/C++ libraries, in an easy and elegant way. Ultimately, a Scala Native application is a native application, with no JVM dependencies.
  • Interoperability with native libraries is a remarkable prospect, because it means that we can have programs (a) written in a strong functional language, that (b) take advantage of the functionality and the performance characteristics of such libraries.
  • Scala Native can already be used to do systems programming. Richard Whaling has written a book on that very topic.

As shown, Scala Native is already meaningful for some areas, while it can become very significant for others. This is what drives us forward and why we are investing in Scala Native.

Current Status

At the moment, Scala Native is mature enough to build fast native applications from Scala projects, with optional C/C++ components. It has its own IR, called the NIR, which translates to LLVM IR and, ultimately, to a native executable.

It also supports low-level primitives, in order to do low-level manipulations, for example on memory, files, etc. It can also seamlessly interoperate with the standard C library, or any external library for that matter.

On the other hand, we are aware that SN falls a little bit behind, as far as the evolution of the Scala language goes (SN currently supports only Scala 2.11). It could also benefit from a simpler and more practical testing framework, with decent reflection support.

Next Steps

Based on all of the above, we are taking the following actions to ensure the Scala Native evolution, both in terms of catching up with the Scala language, as well as making it easier for developers to port their applications.

Short-term goals (within May 2020):

  • We have recently merged reflective instantiation support. We will make sure that the SN testing infrastructure is updated to make use of it. This will hugely simplify the testing infrastructure and will open the way so that developers and library maintainers can easily write native tests for their applications.

Mid-term goals (until September 2020):

  • We will be making sure to upgrade Scala Native to Scala 2.12 and, later, Scala 2.13. This is important because SN needs to evolve together with the Scala language.

We truly believe that Scala Native can become an essential part of the Scala ecosystem. The above actions are the fundamental first steps to be taken towards that objective.

Once we have completed the short and mid-term goals, we can look forward to longer term goals.

Long-term goals:

  • Improve and enhance native interoperability, so that Scala Native can support as many libraries as possible.
  • Keep up with the Scala language releases.

Conclusion

The Scala Center team that will be working on Scala Native will consist of 2 engineers (1 full-time and 1 part-time). You can expect us to be more responsive to issues on Github (this includes the issues that are already open), but we also ask you to please be patient. We are aware there has been a vacuum period and there’s much to catch up with.

In the beginning, we will be prioritising contributions that take us closer to the short-term goals described above. However, all contributions are welcome, so if you have a cool idea, we encourage you to open a PR.

We are looking forward to making progress with SN and we hope that the community will actively participate in this effort, with feedback and contributions.

Stay tuned for updates and we hope that you decide to go native!

- The Scala Center Team

44 Likes

Nice to see a roadmap!

I’m personally pretty excited to see this moving forward. Here are the reasons I think someone might find Scala-Native interesting, even if it is not in a ready-to-use state right now:

  1. Better interop with native C/C++ libraries: this could make it much easier to integrate with the various machine learning and numeric libraries: Tensorflow, Keras, etc., where the overhead of JVM<->Native interop may be inconvenient or slow.

  2. Faster startup time than the JVM: this could be a great benefit for command line tools and the like. For a lot of these use cases, steady state performance doesn’t matter: many people currently use Bash or Python here after all, myself included! Even tools like git, ls, etc. could potentially be written in Scala-Native

  3. Reduced Memory Usage: This could potentially be useful for things like side-car processes and background daemons, which you do not want hogging resources. I believe memory usage is the reason why the Istio folks migrated away from Scala altogether, and a big factor in why people like using languages like Go.

  4. Better Control Over Memory: Scala-Native could allow experimenting with unboxed structs, arena memory allocators, and many other things which are impossible on the JVM runtime. This could potentially greatly reduce the pointer-chasing that tends to happen in JVM applications, and reduce usage of e.g. off-heap memory that some high-performance frameworks like Spark use to sidestep the JVM memory allocator

  5. Better Performance Overall: the JVM was not built for Scala, and it is conceivable that the additional freedom Scala-Native has to do things (e.g. whole-program optimization, unboxed structs, etc.) could allow even better performance than equivalent Scala-JVM programs

My personal use case would mostly be (2), but I can imagine other people may have different use cases. Looking forward to Scala-Native maturing :slight_smile:

32 Likes

I wonder if we could get Microsoft support for developing Scala Native Windows.

1 Like

I’m not sure 2.12 should be in focus. I think it’s best to aim directly for 2.13 and 3.0 (dotty). With 3.0 it’s worth thinking how TASTy can improve compatibility with the native plugin.

6 Likes

All the changes required for 2.12 support are also necessary for 2.13 support. So any work done for 2.12 is a step forward for 2.13. It makes no sense to say “work for 2.13 support” without also working for 2.12 support.

It won’t. Not any more than for Scala.js. I know that TASTy advocates always present this as a selling point, but as author of Scala.js I have been saying all along that this will not be the case.

TASTy will bring benefits, and will bring to Scala.js and Scala Native the same benefits as for Scala/JVM, but it making it easier to write the platform plugins or cross-platform code is emphatically not one of them.

7 Likes

This is wonderful news. I think that @lihaoyi does a great job of laying out reasons why people might be motivated to use Scala Native. I’m personally in the #5 camp myself as I have long wanted to be able to move my numerical simulation work away from C++. Rust is getting to the point where it could be an option, but Scala Native would be even better. I had a student this past semester working on getting the plotting package I’ve put together in Scala to work on Scala.js and Scala Native as well. The majority of his effort went into Scala Native. Having this project brought forward to match the other two compile targets would be wonderful.

11 Likes

One thing I think would help enormously is if we could create Structs in cross platform Scala code. The Structs could just be treated as normal heap classes on Jvm and JavaScript. This would save a lot of code duplication.

2 Likes

Oh, OK. I thought it requires more work to support 2.12, and not that it’s a stepping stone.

And…
6. Compile this thing https://github.com/lihaoyi/Metascala to native code and get rid of Oracle once and for all.

3 Likes

I agree that tasty doesn’t make this easier inherently. However, is it easier for scala-native to Target tasty->NIR as it’s next step vs. upgrading to 2.12?

Does ->2.12->2.13 make the 3.0 jump incrementally easier (in relation to the effort put in) or is it better to skip straight past them and Target tasty->NIR?

I’m assuming there’s things done in ways that aren’t amenable to this, both for NIR and scala.js I just don’t have any insight there and I know you do.

No, that’s not easier. Because TASTy->NIR is reimplementing the whole compiler plugin to live within the dotty compiler (like the effort to do so for Scala.js) plus the effort to port to 2.12 (which is mostly about implementing JDK 8’s default methods in the NIR).

The thing is that is no TASTy-NIR. What we’ll have have is TASTy->Dotty backend->NIR. TASTy or not TASTy, what we have to implement is Dotty backend->NIR, and that builds on the efforts of 2.12->NIR and 2.13->NIR.

The 2.12 efforts are mostly about default methods, which are also necessary for Dotty. And the 2.13 efforts are mostly about the new collection library, as well as the change Seq = immutable.Seq, which are also necessary for Dotty. I can tell you that these are the main efforts because I’ve already done it for Scala.js.

7 Likes

At NASA’s Jet Propulsion Laboratory we are looking at Scala Native for embedded programming (as a research project). Here #4 is essential. We plan to inform the Scala Native community of our findings.

18 Likes

This is very exciting to see!

I’d like to add one more use case / feature that could boost Scala Native in comparison to similar offerings (Graal Native Images, Kotlin Multiplatform): support for alternative architectures, especially arm64.

One of the main reasons Kotlin Multiplatform has done well so far is its support for writing iOS and Android apps with a common Kotlin backend that has been compiled to the respective target’s architecture. Supporting this could help promote Scala as a core language for mobile development by offering options for all the platforms developers target today.

15 Likes

Thanks for bring this back online again. For me it would be very nice to see more useful command line tool can be implemented with scala-native, the native image of scalafmt is cool too.

Another thing I would like to see is packaging scala-native lib as dynamic libraries for other use case.
Once this can be done, caliban/sangria(The graphql implementation in Scala) can be used in other language too.

For me these two are very important.

BTW, If we can implement a high performance networking framework with scala-native, that will unlock so much potentials.

Graal can support Arm64 now

1 Like

Thanks! These were the details I (and others, likely) were missing. TL;DR the scala NIR needs to be updated to account for changes from the language, and this is a necessary requirement for going from Tasty=>NIR. This is a difficult task

Makes total sense. I look forward (immensely) to both scala.js and Scala native!

1 Like

At Taobao, in our messaging platform client team, we write our messing sdk in C++ and provide API for both iOS and Android, which written the UI logic in Objective-C and Java.

And we are looking into Dart/Flutter for UI logic now too. So I can see the Value here.

2 Likes

The website can be updated too.

1 Like

As far as I know, Graal’s support for arm64 is implemented by directly outputting assembly instead of going through LLVM. Scala Native has an advantage here since going through LLVM lets us output bitcode instead of architecture specific binaries so that Apple can perform the appropriate optimizations for each target device.

4 Likes

The thing that I noticed while playing with scala native, is that it doesn’t support the scala library. One reason may be that, due to the lack of a memory garbage collector, calls to methods allocating memory can’t be chained, i.e. list.map(…).filter(…) would result in memory leaks.

Is there a plan in the future to come around that and maybe support the scala library or thats not possible?