- 快召唤伙伴们来围观吧
- 微博 QQ QQ空间 贴吧
- 文档嵌入链接
- 复制
- 微信扫一扫分享
- 已成功复制到剪贴板
a tour of Scala 3
展开查看详情
1 .A Tour of Scala 3 Martin Odersky Scala Days Lausanne June 2019
2 .10th Anniversary Edition of ScalaDays It all started here in 2010
3 .10th Anniversary Edition of ScalaDays It all started here in 2010
4 .Some curious parallels between now and then What was new in 2010? Collections in Scala 2.8 And today? Scala 2.13, with even better collections! First redesign since 2010 100% CanBuildFrom free!
5 .Scala 2.13 • Redesigned collections (à talk by Stefan Zeiger, Wed 17.45) • Updated futures implementation (à talk by Viktor Klang, Wed 14.30) • Language changes: § literal types § partial unification (SI-2712) on by default § by-name implicits § macro annotations § many polishings in details Merged over 1500 pull requests from 162 contributors
6 .More curious parallels between now and then • Scala 2.8 had some breaking language changes. • Should have been named 3.0. • But we already talked about it as 2.8, felt that it was too late to change. • Now in 2019, Scala 3.0 has (almost) arrived!
7 .Roadmap June 2019 All features fleshed out, with Scala 2.13 implementations in Dotty 0.16+ Fall 2019 Feature freeze, Scala 3.0 M1 stabilization complete SIP process write spec, user docs migrate open-source ecosystem flesh out tests, community build compatibility and migration tools Fall 2020 Scala 3.0 final Scala 2.14
8 .A Tour of Scala 3
9 .Best of Scala 3 What are Scala-3’s Nicest Features? • For beginners • For everyday coding ? • For experts ? I’ll give my personal ranking ? of the top 3 of each category. I also did a Twitter survey and will report on that.
10 .Nicest Features for Beginners? • At that level, most of the language stays the same • But there are nevertheless a few improvements worth mentioning … ?
11 .#3: Drop New class StringBuilder(s: String) { def this() = this("") } StringBuilder("abc") // same as new StringBuilder("abc") StringBuilder() // same as new StringBuilder() • new can be omitted from almost all instance creations. • Only needed to disambiguate in an apply method. • No need to define a case class anymore just to get nice constructor calls.
12 .#2: Toplevel Definitions package p type Labelled[T] = (String, T) val a: Labelled[Int] = ("count", 1) def b = a._2 def hello(name: String) = println(i"hello, $name) All kinds of definitions can be written on the toplevel. Package objects are no longer needed, will be phased out.
13 .#1 Enums enum Color { case Red, Green, Blue } Simplest way to define new types with a finite number of values or constructors.
14 .#1 Enums enum Planet(mass: Double, radius: Double) extends java.lang.Enum { private final val G = 6.67300E-11 def surfaceGravity = G * mass / (radius * radius) case MERCURY extends Planet(3.303e+23, 2.4397e6) case VENUS extends Planet(4.869e+24, 6.0518e6) case EARTH extends Planet(5.976e+24, 6.37814e6) case MARS extends Planet(6.421e+23, 3.3972e6) ... } can have parameters can define fields and methods can interop with Java
15 .#1 Enums enum Option[+T] { case Some(x: T) case None } can have type parameters, making them algebraic data types (ADTs)
16 .#1 Enums sealed abstract class Option[+T] object Option { case class Some[+T](x: T) extends Option[T] object Some { def apply[T](x: T): Option[T] = Some(x) } val None = new Option[Nothing] { ... } } compile to sealed hierarchies of case classes and objects.
17 .#1 Enums enum Tree[T] { case True extends Tree[Boolean] case False extends Tree[Boolean] case IsZero(n: Tree[Int]) extends Tree[Boolean] case Zero extends Tree[Int] case Succ(n: Tree[Int]) extends Tree[Int] case If(cond: Tree[Boolean], thenp: Tree[T], elsep: Tree[T]) extends Tree[T] } can be GADTs (generalized ADTs). à cases can extend the base type with different type arguments.
18 .The public vote:
19 .Why Enums? • Lots of use cases, and they are becoming more common. • Avoids boring, repetitive boilerplate. • Can grow from very simple to very powerful.
20 .Nicest Features for Everyday Coding? • There are lots of candidates. • Hard to come up with a shortlist. ?
21 .#3 Union Types case class UserName(name: String) case class Password(hash: Hash) def help(id: UserName | Password) = { val user = id match { case UserName(name) => lookupName(name) case Password(hash) => lookupPassword(hash) } ... } Provide ad-hoc combinations of types Subsetting = Subtyping No boxing overhead
22 .#3 Union Types type Command = ”Click" | ”Drag" | ”KeyPressed" def handleEvent(kind: Command) = kind match { case “Click" => MouseClick() case ”Drag" => MoveTo() case ”KeyPressed" => KeyPressed() } Work also with singleton types Great for JS interop
23 .#2 Extension Methods object StringOps { def (s: String) * (x: Int): String = if (x <= 0) “” else s * (x - 1) ++ s } import StringOps._ "hello" * 3 Replace implicit classes Make it easier to add methods to existing classes.
24 .#1 Delegates trait Ord[T] { def (x: T) compareTo (y: T): Int def (x: T) < (y: T) = x.compareTo(y) < 0 } delegate IntOrd for Ord[Int] { def (x: Int) compareTo (y: Int) = if (x < y) -1 else if (x > y) +1 else 0 } def maximum[T](xs: List[T]) given Ord[T] = xs.reduce((x, y) => if (x < y) y else x) Replace “implicit” as a modifier Express intent instead of mechanism
25 .#1 Delegates trait SemiGroup[T] { def (x: T) combine (y: T): T } trait Monoid[T] extends SemiGroup[T] { def unit: T } delegate for Monoid[String] { def (x: String) combine (y: String) = x.concat(y) def unit = "" } def sum[T: Monoid](xs: List[T]): T = xs.foldLeft( the[Monoid[T]].unit )(_.combine(_)) Work out of the box with extension methods Provide a nice syntax for typeclasses
26 .#1 Delegates tame implicit conversions implicit def intToStr(str: String): Token = new Keyword(str) What’s wrong with this? It’s too easy to write compared to how dangerous it is. Implicit as a modifier will go away, and with it this kind of conversion.
27 .#1 Delegates The only way to express implicit conversions is as a delegate for a standard Conversion class: delegate for Conversion[String, Token] { def apply(str: String): Token = new KeyWord(str) } Or, using an alias delegate: delegate for Conversion[String, Token] = new KeyWord(_)
28 .The public vote:
29 .Why Delegates? Implicits are Scala’s most distinguished feature. But they are also the most controversial one. Delegates are a simpler and safer alternative. They • emphasize intent over mechanism • make idea of term inference more accessible • discourage abuses