Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with...

34
Migrating to Scala 2.13 Julien Richard-Foy, Scala Center Stefan Zeiger, Lightbend

Transcript of Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with...

Page 1: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

Migrating to Scala 2.13Julien Richard-Foy, Scala Center

Stefan Zeiger, Lightbend

Page 2: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

Scala 2.13

Page 3: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

• Simplifying the collections• Compiler performance• Modularizing the standard library• User-friendliness

https://github.com/scala/scala-dev/issues/324

Scala 2.13 Roadmap

Page 4: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

• Scala 2.13.0-M4 to be released shortly• First milestone with the new collections library

• Final milestone release: M5• Minor API changes, bug fixes and performance improvements

Current Status

Page 5: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

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

Starting Point

Page 6: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

Prepare for migration

Page 7: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

• 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"

Clean up on 2.12: Deprecations

Page 8: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

• 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

Clean up on 2.12: Compiler flags

Page 9: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

• Argument adaptation cannot be turned off selectively any more• -Yno-adapted-args removed

• Dotty has more restrictive adaptation• 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)

Clean up on 2.12: Argument adaptation / Auto-tupling

Page 10: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

• 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

• scala-xml is no longer a transitive dependency of scala-compiler• Depend on it directly if necessary

Clean up on 2.12: Modules

Page 11: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

Build on 2.13

Page 12: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

crossScalaVersions := Seq("2.13.0-M4-pre-20d3c21", "2.12.6")

scalaVersion := crossScalaVersions.value.head

Cross-building: Basic setup

Page 13: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

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

})

Cross-building: Compiler options

Page 14: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

• 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

Build on 2.13

Page 15: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

• 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/

scala-collection-compat

Page 16: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

• build.sbt:libraryDependencies +="org.scala-lang" %% "scala-collection-compat" % "0.1"

• Old Scala code:xs.to[List]

• New Scala code:import scala.collection.compat._xs.to(List)

scala-collection-compat: Example

Not yet available

Page 17: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

New collections

Page 18: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

• 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)

Goals of the collections redesign

Page 19: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

• 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

Major collection incompatibilities: Immutable Seq

Page 20: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

• 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

Major collection incompatibilities: Immutable Seq

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

Page 21: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

• CanBuildFrom replaced by BuildFrom• BuildFrom requires an instance of the source collection:

trait BuildFrom[-From, -A, +C] {def fromSpecificIterable(from: From)(it: Iterable[A]): Cdef newBuilder(from: From): Builder[A, C]

}

• Used in methods like Future.sequence• Collection methods like flatMap no longer need it

• Overloaded to produce different results depending on source collection type

Major collection incompatibilities: CanBuildFrom

Page 22: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

• 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]): Cdef newBuilder: Builder[A, C]

}

• General rule: Use BuildFrom to rebuild with the best matching type of an existing source collection, otherwise use Factory

Major collection incompatibilities: CanBuildFrom

Page 23: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

• 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:

val xs: List[Future[Int]] = …Future.sequence(xs)(breakOut, implicitly):Future[Vector[Int]]

• New:val xs: List[Future[Int]] = …Future.sequence(xs)(Vector, implicitly)

Major collection incompatibilities: breakOut

Doesn't actually work in 2.12

Page 24: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

• Views in the new collections are reified Iterator operations• View vs Iterator is similar to Stream vs Spliterator in Java 8

collections• 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

Major collection incompatibilities: Views

Page 25: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

• 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

Major collection incompatibilities: Custom collections

Page 26: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

crossScalaVersions := Seq("2.13.0-M4-pre-20d3c21", "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.13unmanagedSourceDirectories in Compile += {

val sourceDir = (sourceDirectory in Compile).valueCrossVersion.partialVersion(scalaVersion.value) match {

case Some((2, n)) if n >= 13 => sourceDir / "scala-2.13+"case _ => sourceDir / "scala-2.12-"

}}

Cross-building: Source directories

sbt already gives you:• scala• scala-2.12• scala-2.13.0-M4-pre-20d3c21

Page 27: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

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

Major collection incompatibilities

Page 28: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

Automated migration

Page 29: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

2.12 2.13Scalafix

manual work

Migrating an application Rules under development –more in M5

Page 30: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

• plugins.sbt:addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.5.7")

• From your shell:$ sbt> scalafixEnable> scalafix github:scala/scala-collection-compat/NewCollections

• build.sbt:scalaVersion := "2.13.0"

• And then:> ;reload ;compile

• Documentation: https://github.com/scala/scala-collection-compat

Running the migration rulesStep 1: Add sbt-scalafix to

your project

Step 2: Run the migration rule

Step 3: Update the scalaVersion

Page 31: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

• 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

Scope of the migration rulesHas a lazy head

Page 32: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

• Custom collection implementations• Advanced usage of CanBuildFrom• scala.Seq usage

• Comprehensive list of supported rewrites:https://github.com/scala/collection-strawman/wiki/FAQ

Not in the scope of the migration

Page 33: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

2.112.12

2.112.122.13

Scalafix

scala-collection-compat

manual work

Migrating a library Rules not yet implemented

Page 34: Migratingto Scala 2 - Trifork · •Scala 2.13.0-M4 to be released shortly •First milestone with the new collections library •Final milestone release: M5 •Minor API changes,

• Draft of "The Architecture of Scala Collections" for 2.13: https://github.com/scala/docs.scala-lang/pull/960

• Demo project for cross-building:https://github.com/szeiger/new-collections-demo

• FAQ: https://github.com/scala/collection-strawman/wiki/FAQ• Previous talks on the new collections:• The new collections library for Scala 2.13 and Dotty• The next() collections

• @julienrf• @StefanZeiger

Links