value classes in scala - · pdf filevalue classes in scala • introduced in scala 2.10.0...
TRANSCRIPT
![Page 1: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/1.jpg)
Value Classes in Scala
Lukas Rytz, Typesafe
![Page 2: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/2.jpg)
Value Classes in Scala
• Introduced in Scala 2.10.0 (January 2013)
• Release Notes:
2
,A class may now extend AnyVal to make it behave like a struct type (restrictions apply).
![Page 3: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/3.jpg)
Agenda
• Introduction to value classes
• Compiler transformation: an example
• Value classes in Scala's type hierarchy
• Limitations and feature interactions
3
![Page 4: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/4.jpg)
Main Idea
• Value class instances are inlined: represented at runtime as their fields
↣ Space: no object header, no work for GC
↣ Locality: no pointer chasing
↣ Convenient for programmers (normal classes)
4
![Page 5: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/5.jpg)
Implications of this Representation
• Values (value class instances) have no object identity
↣ No locking on values, identityHashCode, ...
• Fields of values are immutable
↣ Values are passed "by value" (copied)
5
![Page 6: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/6.jpg)
Some Use Cases• Extension methods without overhead
• Bit fields: Mode in scalac's type checker, Flags
• Semantic primitives: units of measure
• New numeric types like Complex ↣ FastComplex in spire: two floats in one long ↣ (Scala has only single-field value classes)
6
![Page 7: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/7.jpg)
Agenda
• Introduction to value classes
• Compiler transformation: an example
• Value classes in Scala's type hierarchy
• Limitations and feature interactions
7
![Page 8: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/8.jpg)
Example: Extension Method
8
object Predef { implicit class Ar[A](private val a: A) extends AnyVal { def -‐> [B](b: B): Tuple2[A, B] = Tuple2(a, b) } } !scala> "jan" -‐> "january" res0: (String, String) = (jan,january)
![Page 9: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/9.jpg)
Example: extension method
9
object Predef { implicit class Ar[A](private val a: A) extends AnyVal { def -‐> [B](b: B): Tuple2[A, B] = Tuple2(a, b) } } !scala> "jan" -‐> "january" res0: (String, String) = (jan,january)
![Page 10: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/10.jpg)
-Xprint:parser
10
implicit class Ar[A] extends AnyVal { private val a: A = _ def <init>(a: A) = super.<init>() def -‐>[B](b: B): Tuple2[A, B] = Tuple2(a, b) }
Parser
Type Checker
Extension Methods
Erasure
![Page 11: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/11.jpg)
11
final class Ar[A] extends AnyVal { private[this] val a: A = _ private def a: A = this.a ! def <init>(a: A): Ar[A] = super.<init>() def -‐>[B](b: B): (A, B) = Tuple2.apply[A, B](a, b) ! override def hashCode(): Int = ... override def equals(x$1: Any): Boolean = ... } !implicit def Ar[A](a: A): Ar[A] = new Ar[A](a)
-Xprint:typerParser
Type Checker
Extension Methods
Erasure
![Page 12: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/12.jpg)
12
final class Ar[A] extends AnyVal { // Field, constructor ! def -‐>[B](b: B): (A, B) = Ar.-‐>$extension[B, A](this)(b) ! // Similar for hashCode, equals } !object Ar extends AnyRef { def -‐>$extension[B, A]($this: Ar[A])(b: B): (A, B) = Tuple2.apply[A, B]($this.a, b) ! // similar for hashCode, equals } !implicit def Ar[A](a: A): Ar[A] = new Ar[A](a)
-Xprint:extmethodsParser
Type Checker
Extension Methods
Erasure
![Page 13: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/13.jpg)
final class Ar extends Object { private[this] val a: Object = _ final def a(): Object = this.a def <init>(a: Object): Ar = super.<init>() def -‐>(b: Object): Tuple2 = Ar.-‐>$extension(this.a(), b) } !!object Ar extends Object { def -‐>$extension($this: Object, b: Object): Tuple2 = new Tuple2($this, b) } !!implicit def Ar(a: Object): Object = a
-Xprint:posterasure
13
Ar[A] ⟹ A ⟹ Object
new Ar(a) ⟹ a
Ar[A] ⟹ ArA ⟹ Object
$this.a() ⟹ $this
Parser
Type Checker
Extension Methods
Erasure
![Page 14: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/14.jpg)
Example: extension method
14
object Predef { implicit class Ar[A](private val a: A) extends AnyVal { def -‐> [B](b: B): Tuple2[A, B] = Tuple2(a, b) } } !scala> "jan" -‐> "january" res0: (String, String) = (jan,january)
![Page 15: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/15.jpg)
Client Code
15
class C { def f = "jan" -‐> "january" } !// After typer class C extends AnyRef { def f: Tuple2[String, String] = Ar[String]("jan").-‐>[String]("january") } !// After erasure class C extends Object { def f(): Tuple2 = ArrowAssoc.-‐>$extension(Ar("jan"), "january") }
No boxing!
![Page 16: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/16.jpg)
Agenda
• Introduction to value classes
• Compiler transformation: an example
• Value classes in Scala's type hierarchy
• Limitations and feature interactions
16
![Page 17: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/17.jpg)
Defining Value Classes• No fields, only (one single) class parameter
• No initializer statements
• The wrapped value may not be a value class ↣ Not yet implemented
• hashCode and equals cannot be user-defined
• Value classes extend AnyVal
17
![Page 18: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/18.jpg)
Type Hierarchy
18
AnyVal
Any
AnyRef (j.l.Object)
Int
Boolean
Classes, Traits
Nothing
Null
Value Classes
![Page 19: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/19.jpg)
Type Hierarchy
19
AnyVal
Any
AnyRef (j.l.Object)
Int
Boolean
Classes, Traits
Nothing
Null
Value Classes
synchronizedcannot be null
![Page 20: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/20.jpg)
Extending Traits
• Traits may have fields, initializers ↣ Not suitable as parents for value classes
• Value classes can extend universal traits ↣ Universal traits extend Any
↣ No fields, no synchronization
20
![Page 21: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/21.jpg)
Type Hierarchy
21
AnyVal
Any
AnyRef (j.l.Object)
Int
Boolean
Universal Traits
Classes, Traits
Nothing
Null
Value Classes
synchronizedcannot be null
![Page 22: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/22.jpg)
Agenda
• Introduction to value classes
• Compiler transformation: an example
• Value classes in Scala's type hierarchy
• Limitations and feature interactions
22
![Page 23: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/23.jpg)
Boxing
23
• Assigning a value to a supertype (parent trait, AnyVal, Any)
• Generics: no specialization for value classes (yet) ↣ For data structures and methods
• Values stored in arrays ☹
↣ Need meters.isInstanceOf[Array[Meter]]
![Page 24: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/24.jpg)
Trait Method Calls
24
trait Super extends Any { def x: Int def f = this.x } !def t1(s: Super) = s.f !!class Value(val x: Int) extends AnyVal with Super !def t2(v: Value) = v.f
Needs to be a virtual call. Requires an object.
Code of f (compiled separately) assumes existence of an instance
![Page 25: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/25.jpg)
Performance Model• Boxing is implicit: the code does not reveal the
representation
• Difficult for users: requires knowledge about the limitations
• Scala favours uniformity in other places, e.g., ↣ while / for loops ↣ Collections of primitives
25
![Page 26: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/26.jpg)
Overloading Restrictions
26
class Meter(val x: Double) extends AnyVal class Mile(val x: Double) extends AnyVal !trait Distance { def add(m: Meter): Distance def add(m: Mile): Distance } !error: double definition: def add(m: Meter): Distance def add(m: Mile): Distance have same type after erasure: (m: Double)Distance
![Page 27: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/27.jpg)
Manifestation at Bridges
27
class C[T](val x: T) extends AnyVal !trait T[A] { def f: A } !class K extends T[C[Object]] { def f: C[Object] = .. } !!error: bridge generated for member method f: ()C[Object] in class K which overrides method f: ()A in trait T clashes with definition of the member itself; both have erased type ()Object
![Page 28: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/28.jpg)
Extending Java Interfaces
28
https://groups.google.com/forum/#!topic/scala-internals/12h2TgDFnDM https://groups.google.com/forum/#!topic/scala-internals/jsVlJI4H5OQ
• Java interfaces in Scala are subtypes of AnyRef
• Making them universal (extend Any) is source-incompatible def f(i: JavaIface) = i.synchronized { .. }
• Hack for Serializable, Comparable
↣ Allow case classes to be value classes ↣ Scala library has value classes extending Comparable
![Page 29: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/29.jpg)
Option[T] value class?
29
scala> Set[String](null, "hi") find (_ == null) res: Option[String] = Some(null)
https://groups.google.com/forum/#!topic/scala-language/Mz_VoJdJf1w
null None Some(null) Some(x)
null x
![Page 30: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/30.jpg)
Feature Interactions in the Compiler
• Implementation in the compiler is difficult at the edges
• Examples from the issue tracker ↣ VCs + type bounds: compiler crash (SI-6304) ↣ VC method with lazy val: compiler crash (SI-6358) ↣ VC with private[this] method: compiler crash
(SI-7019)
30
![Page 31: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/31.jpg)
Future: Multiple Fields
• Doable on today's VM
• Investment vs. return, given the limitations ↣ Returns require boxing (or other tricks) ↣ Boxing in arrays ↣ Writes to fields are not atomic
31
![Page 32: Value Classes in Scala - · PDF fileValue Classes in Scala • Introduced in Scala 2.10.0 (January 2013) • Release Notes: 2, A class may now extend AnyVal to make it behave like](https://reader031.vdocuments.us/reader031/viewer/2022022003/5aa22e807f8b9aa0108cdc05/html5/thumbnails/32.jpg)
Future
• Integrate with specialization
• Re-implement on top of the VM support ↣ Profit: arrays of values, return multiple values ↣ Compatibility with the rest of the ecosystem
(e.g., reflection)
32