migrating to scala 2 13
play

Migrating to Scala 2.13 Ju Julien Richar ard-Fo Foy , Scala Center - PowerPoint PPT Presentation

Migrating to Scala 2.13 Ju Julien Richar ard-Fo Foy , Scala Center St Stefan Zeiger , Lightbend Scala 2.13 Scala 2.13 Roadmap Simplifying the collections Compiler performance Modularizing the standard library User-friendliness


  1. Migrating to Scala 2.13 Ju Julien Richar ard-Fo Foy , Scala Center St Stefan Zeiger , Lightbend

  2. Scala 2.13

  3. Scala 2.13 Roadmap • Simplifying the collections • Compiler performance • Modularizing the standard library • User-friendliness https://github.com/scala/scala-dev/issues/324

  4. Current Status • Scala 2.13.0-M4 released one month ago during ScalaDays Berlin • First milestone with the new collections library • Final milestone release: M5 (August 10) • Minor API changes • Bug fixes • Performance improvements • Compatibility improvements

  5. Starting Point • Project that works on Scala 2.12 • Targeting Scala 2.13.0-M4 or higher • sbt build (for examples shown)

  6. Prepare for migration

  7. Clean up on 2.12: Deprecations • Remove deprecated calls • Many deprecated APIs were removed in 2.13 (e.g. JavaConversions ) • A clean build without deprecations on 2.12 makes the migration easier • build.sbt: scalacOptions in Compile += "-deprecation"

  8. Clean up on 2.12: Compiler flags • Compiler flags that modify the language are being removed in 2.13 • Only -Xsource from now on • Compile without the following flags: • -Yno-adapted-args • -Xstrict-inference • -Xfull-lubs • -Yoverride-objects • -Yoverride-vars • -Yinfer-argument-types • -Yvirtpatmat • See https://github.com/scala/scala/pull/6505

  9. Clean up on 2.12: Argument adaptation / Auto-tupling • Argument adaptation cannot be turned off selectively any more • -Yno-adapted-args removed • Dotty has more restrictive adaptation • Goal: Always allow safe adaptation, prohibit unsafe (accidental) cases • Scala 2.14 will align with Dotty rules • Automatic eta-expansion of zero-arg methods already disabled in 2.13 under -Xsource:2.14 (see https://github.com/scala/scala/pull/6475) • But more aggressive eta-expansion of other methods

  10. Clean up on 2.12: Modules • scala-library-all has been removed • Depend on the required modules individually • Parallel collections have been moved into a separate module • Add a dependency to scala-parallel-collections on 2.13 and see https://github.com/scala/scala-parallel-collections/issues/22 for cross- building • Not available for M4, will be published again for M5 • scala-xml is no longer a transitive dependency of scala-compiler • Not used by scaladoc anymore • Depend on it directly if necessary

  11. Build on 2.13

  12. Cross-building: Basic setup crossScalaVersions := Seq("2.13.0-M4", "2.12.6") scalaVersion := crossScalaVersions.value.head

  13. Cross-building: Compiler options scalacOptions ++= (CrossVersion.partialVersion(scalaVersion.value) match { case Some((2, n)) if n >= 13 => Seq("-Xsource:2.14") case _ => Seq("-Yno-adapted-args") })

  14. Build on 2.13 • Expect some breakage due to the new collections library • Singleton types and minor type inference changes can influence types and implicit resolution in corner cases • Other small changes in source compatibility (see https://github.com/scala/scala- dev/issues/470) • Try -Xsource:2.12

  15. scala-collection-compat • The new collections library is mostly source compatible • Many old methods and types are deprecated • e.g. Traversable , TraversableOnce , Stream , ... • Some features could not be added back in a 2.12-compatible way • Instead scala-collection-compat provides the 2.13 syntax on 2.11 & 2.12 • https://github.com/scala/scala-collection-compat/

  16. scala-collection-compat: Example • build.sbt: libraryDependencies += "org.scala-lang.modules" %% "scala-collection-compat" % "0.1.0" • Old Scala code: xs.to[List] • New Scala code: import scala.collection.compat._ xs.to(List)

  17. New collections

  18. Goals of the collections redesign • This is not the topic of this talk, but in short: • Simpler user-facing API (no CanBuildFrom ) • Correct operation implementations for non-strict collections • Simpler internal hierarchy (no Gen… types)

  19. Major collection incompatibilities: Immutable Seq • scala.Seq is now scala.collection. immutable .Seq • Same for IndexedSeq • Consistent with Set and Map • Decide on a case-by-case basis which one to use • Use s.c.Seq or s.c.i.Seq explicitly when cross-building

  20. Major collection incompatibilities: Immutable Seq • Varargs use scala.Seq , so also immutable now • Wrapped Java varargs pretend the array is immutable • Using the new s.c.i.ArraySeq • You can do the same with ArraySeq.unsafeWrapArray • A deprecated implicit conversion makes a copy of the array method copyArrayToImmutableIndexedSeq in class LowPriorityImplicits2 is deprecated (since 2.13.0): Implicit conversions from Array to immutable.IndexedSeq are implemented by copying; Use the more efficient non-copying ArraySeq.unsafeWrapArray or an explicit toIndexedSeq call

  21. Major collection incompatibilities: CanBuildFrom • CanBuildFrom replaced by BuildFrom • BuildFrom requires an instance of the source collection: trait BuildFrom[-From, -A, +C] { def fromSpecificIterable( from: From )(it: Iterable[A]): C def newBuilder( from: From ): Builder[A, C] } • Collection methods like flatMap no longer need it • Overloaded to produce different results depending on source collection type • Used in methods like Future.sequence

  22. Major collection incompatibilities: CanBuildFrom • Factory allows target type-driven building (like CanBuild in 2.12) • Used in Iterable.to • Like BuildFrom but does not use a source collection: trait Factory[-A, +C] { def fromSpecific(it: IterableOnce[A]): C def newBuilder: Builder[A, C] } • General rule: Use BuildFrom to rebuild with the best matching type of an existing source collection, otherwise use Factory

  23. Major collection incompatibilities: breakOut • Without CanBuildFrom , there is no breakOut Use an Iterator : xs.iterator.map(…).to(Vector) • • Methods with BuildFrom or Factory can be called with a companion object instead (via implicit conversion to BuildFrom / Factory ): • Old: Doesn't actually work in 2.12 val xs: List[Future[Int]] = … Future.sequence(xs)( breakOut , implicitly): Future[ Vector [Int]] • New: val xs: List[Future[Int]] = … Future.sequence(xs)( Vector , implicitly)

  24. Major collection incompatibilities: Views • Views in the new collections are reified Iterator operations • View vs Iterator is similar to Stream vs Spliterator in Java 8 streams • Views don't remember source collection types • Use an explicit to… operation instead of force to build the desired type • mapValues and filterKeys on Map now return MapView • It was always a lazy View -like object but pretended to be a Map • Add .toMap if necessary

  25. Major collection incompatibilities: Custom collections • Only very simple collection implementations are source compatible • General rule: Use two different source files in different source directories to cross-build • Type hierarchy simplified • Less boilerplate • All methods have alphabetic names, symbolic operators are aliases • E.g. override concat instead of ++ • Overloading instead of CanBuildFrom

  26. Cross-building: Source directories crossScalaVersions := Seq("2.13.0-M4", "2.12.6") scalaVersion := crossScalaVersions.value.head // Add src/main/scala-2.13+ for Scala 2.13 and newer // and src/main/scala-2.12- for Scala versions older than 2.13 unmanagedSourceDirectories in Compile += { val sourceDir = (sourceDirectory in Compile).value CrossVersion.partialVersion(scalaVersion.value) match { case Some((2, n)) if n >= 13 => sourceDir / "scala-2.13+" case _ => sourceDir / "scala-2.12-" } } sbt already gives you: • scala • scala-2.12 • scala-2.13.0-M4

  27. Major collection incompatibilities • See https://github.com/scala/collection-strawman/wiki/FAQ for a more comprehensive list

  28. Automated migration

  29. Migrating an application Rules under development – more in M5 2.12 2.13 Scalafix manual work

  30. Running the migration rules Step 1: Add sbt-scalafix to your project plugins.sbt: • addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.5.7") From your shell: • Step 2: Run the migration $ sbt rule > scalafixEnable > scalafix github:scala/scala-collection- compat/NewCollections build.sbt: • Step 3: Update the scalaVersion := "2.13.0-M4" scalaVersion And then: • > ;reload ;compile Documentation: https://github.com/scala/scala-collection-compat •

  31. Scope of the migration rules Has a lazy head • Renamings • Stream(1, 2, 3).append(Stream(4, 5, 6)) • LazyList(1, 2, 3).lazyAppendedAll(LazyList(4, 5, 6)) • Expression rewritings xs.copyToBuffer(b) • b ++= xs • The more complex the expression, the harder to implement the rewrite rule •

  32. Not in the scope of the migration rules • Custom collection implementations • Advanced usage of CanBuildFrom • scala.Seq usage • Comprehensive list of supported rewrites: https://github.com/scala/collection-strawman/wiki/FAQ

  33. Migrating a library Rules not yet implemented 2.11 2.11 2.12 Scalafix 2.12 2.13 manual work scala-collection-compat

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend