migrating to scala 2 - lightbend€¦ · • scala 2.13.0-m4 released one month ago during...

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

Upload: others

Post on 22-May-2020

4 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

Migrating to Scala 2.13Julien Richard-Foy, Scala Center

Stefan Zeiger, Lightbend

Page 2: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

Scala 2.13

Page 3: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

• 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: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

• 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

Current Status

Page 5: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

• Project that works on Scala 2.12

• Targeting Scala 2.13.0-M4 or higher• sbt build (for examples shown)

Starting Point

Page 6: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

Prepare for migration

Page 7: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

• 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: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

• 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: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

• 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

Clean up on 2.12: Argument adaptation / Auto-tupling

Page 10: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

• 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

Clean up on 2.12: Modules

Page 11: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

Build on 2.13

Page 12: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

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

scalaVersion := crossScalaVersions.value.head

Cross-building: Basic setup

Page 13: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

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: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

• 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: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

• 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: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

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

scala-collection-compat: Example

Page 17: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

New collections

Page 18: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

• 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: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

• 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: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

• 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: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

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

}• Collection methods like flatMap no longer need it

• Overloaded to produce different results depending on source collection type• Used in methods like Future.sequence

Major collection incompatibilities: CanBuildFrom

Page 22: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

• 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: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

• 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: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

• 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

Major collection incompatibilities: Views

Page 25: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

• 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: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

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.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

Page 27: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

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

Major collection incompatibilities

Page 28: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

Automated migration

Page 29: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

2.12 2.13Scalafix

manual work

Migrating an application Rules under development –more in M5

Page 30: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

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

• 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: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

• 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: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

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

Page 33: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

2.112.12

2.112.122.13

Scalafix

scala-collection-compat

manual work

Migrating a library Rules not yet implemented

Page 34: Migrating to Scala 2 - Lightbend€¦ · • Scala 2.13.0-M4 released one month ago during ScalaDaysBerlin • First milestone with the new collections library • Final milestone

• "The Architecture of Scala 2.13’s Collections": https://docs.scala-lang.org/overviews/core/architecture-of-scala-213-collections.html

• 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