user1804599
user1804599

Reputation:

How does Dotty desugar polymorphic methods?

Dotty reportedly desugars classes with type parameters to classes with type members, for example:

class C[T, U] { }
// <=>
class C {
  type C$T
  type C$U
}

How does Dotty desugar polymorphic methods like in the following example?

def m[T, U](x: T, u: U): T = x
// <=>
?

Upvotes: 2

Views: 225

Answers (2)

J&#246;rg W Mittag
J&#246;rg W Mittag

Reputation: 369516

You may want to start at the bottom of page 13, section 5.2 of the most recent DOT paper The Essence of DOT by Nada Amin, Samuel Grütter, Martin Odersky, Tiark Rompf, and Sandro Stucki. It shows the implementation of a simple covariant polymorphic List[+A] type in Scala. Of particular note is the polymorphic cons[A] method:

package scala.collection.immutable

trait List[+A] {
  def isEmpty: Boolean
  def head: A
  def tail: List[A]
}

object List {
  def cons[A](hd: A, tl: List[A]) = new List[A] {
    def isEmpty = false
    def head = hd
    def tail = tl
  }
}

And how it is encoded in DOT:

let scala_collection_immutable = ν(sci) {
  List = μ(self: {A; isEmpty: bool.Boolean; head: self.A; tail: sci.List∧{A <: self.A}})

cons: ∀(x: {A})∀(hd: x.A)∀(tl: sci.List∧{A <: x.A})sci.List∧{A <: x.A} =
  λ(x: {A})λ(hd: x.A)λ(tl: sci.List∧{A <: x.A})
    let result = ν(self) {
      A = x.A; isEmpty = bool.false; head = hd; tail = tl }
    in result
}: { μ(sci: {
  List <: μ(self: {A; head: self.A; tail: sci.List∧{A <: self.A}})

  cons: ∀(x: {A})∀(hd: x.A)∀(tl: sci.List∧{A <: x.A})sci.List∧{A <: x.A}
})}
in …

Which in turn should give you an intuition how it is encoded in Dotty.

Page 15 then shows you how the desugared DOT can be mapped back to Scala:

object scala_collection_immutable { sci => 
  trait List { self =>
    type A
    def isEmpty: Boolean
    def head: self.A
    def tail: List{type A <: self.A}
  }

  def cons(x: {type A})(hd: x.A)(tl: sci.List{type A <: x.A}) 
    : sci.List{type A <: x.A} = new List{ self =>
    type A = x.A
    def isEmpty = false
    def head = hd
    def tail = tl
  }
}

As you can see, the encoding of a polymorphic method is more or less the same as a polymorphic trait: the type parameter becomes an abstract type member, in this case an abstract type member of a refinement type (aka structural type):

x : A
// becomes
x : {type A}

Upvotes: 2

sjrd
sjrd

Reputation: 22095

Unlike polymorphic classes, polymorphic methods are not desugared. They fundamentally stay polymorphic.

Upvotes: 5

Related Questions