SlideShare una empresa de Scribd logo
1 de 71
Descargar para leer sin conexión
TI1220 2012-2013
Concepts of Programming Languages
Eelco Visser / TU Delft
Lecture 8: Traits & Type Parameterization
var ms := course.managers;
var ms : Set<Person> := Set<Person>();
ms.addAll(course.managers);
Analysis => Lecture 12: Concurrency
Root Cause
The Fix
Intention: copy
semantics
Effect: reference
semantics
The Fault: Concurrent writes on CourseEdition
The Airconditioning
Syntax and Semantics
Names, Bindings, and Scopes
Storage
Data Types
Functional Programming
First-class Functions
Polymorphism
Traits & Type Parameterization
Parsing and Interpretation
Data Abstraction / Modular Programming
Functional Programming Redux
Concurrency
Concurrent Programming
Domain-Specific Languages
Quarter 3
Quarter 4
Basics of
Scala
JavaScript
C
Traits
abstract class Element {
def contents: Array[String]
def height: Int = contents.length
def width: Int = if (height == 0) 0
else contents(0).length
}
class ArrayElement(conts: Array[String]) extends Element {
val contents: Array[String] = conts
}
Classical Inheritance
Inheriting fields and methods
class UniformElement(
ch: Char,
override val width: Int,
override val height: Int
) extends Element {
private val line = ch.toString * width
def contents = Array.make(height, line)
}
val e1: Element = new ArrayElement(Array("hello", "world"))
val ae: ArrayElement = new LineElement("hello")
val e2: Element = ae
val e3: Element = new UniformElement('x', 2, 3)
Subtyping
abstract class Element {
def demo() {
println("Element's implementation invoked")
}
}
class ArrayElement extends Element {
override def demo() {
println("ArrayElement's implementation invoked")
}
}
class LineElement extends ArrayElement {
override def demo() {
println("LineElement's implementation invoked")
}
}
// UniformElement inherits Element’s demo
class UniformElement extends Element
def invokeDemo(e: Element) {
e.demo()
}
scala> invokeDemo(new ArrayElement)
ArrayElement's implementation invoked
scala> invokeDemo(new LineElement)
LineElement's implementation invoked
scala> invokeDemo(new UniformElement)
Element's implementation invoked
Dynamic Binding
Subtyping
• Polymorphism & dynamic binding
Code Reuse
• reuse instance variables and methods from super class
Single Inheritance
• cannot reuse code from more than one class
Interfaces
• support subtyping multiple classes
• must re-implement interface
Java-style Single Inheritance
Trait
• reusable unit of code
• encapsulates method and field definitions
• reused by mixing into classes
• class can mix in any number of traits
Applications
• rich interfaces
• stackable modifications
trait Philosophical {
def philosophize() {
println("I consume memory, therefore I am!")
}
}
class Frog extends Philosophical {
override def toString = "green"
}
scala> val frog = new Frog
frog: Frog = green
scala> frog.philosophize()
I consume memory, therefore I am!
scala> val phil: Philosophical = frog
phil: Philosophical = green
scala> phil.philosophize()
I consume memory, therefore I am!
inheritance: code reuse subtyping: traits are types
Defining and Using Traits
class Animal
trait HasLegs
class Frog extends Animal with Philosophical with HasLegs {
override def toString = "green"
override def philosophize() {
println("It ain't easy being " + toString + "!")
}
}
superclass
traits
override code from trait
scala> val phrog: Philosophical = new Frog
phrog: Philosophical = green
scala> phrog.philosophize()
It ain't easy being green!
Mixing in (multiple) traits
Trait is like Java interface with
• methods
• fields
• state
Trait is Scala class
• without class parameters
• dynamic binding of ‘super’
Rich interface
• many methods
• convenient for client
• more work for implementer
Thin interface
• few methods
• easy for implementers
• inconvenient for client
trait CharSequence {
def charAt(index: Int): Char
def length: Int
def subSequence(start: Int, end: Int): CharSequence
def toString(): String
}
Rich Interfaces with Traits
• small number of abstract
methods implemented by
client
• large number of concrete
methods inherited by client
class Point(val x: Int, val y: Int)
class Rectangle(val topLeft: Point, val bottomRight: Point)
{
def left = topLeft.x
def right = bottomRight.x
def width = right - left
// and many more geometric methods...
}
abstract class Component {
def topLeft: Point
def bottomRight: Point
def left = topLeft.x
def right = bottomRight.x
def width = right - left
// and many more geometric methods...
}
Rectangular objects without traits
trait Rectangular {
def topLeft: Point
def bottomRight: Point
def left = topLeft.x
def right = bottomRight.x
def width = right - left
// and many more geometric methods...
}
abstract class Component extends Rectangular {
// other methods...
}
class Rectangle(val topLeft: Point, val bottomRight: Point)
extends Rectangular {
// other methods...
}
Rectangular objects with traits
trait Rectangular {
def topLeft: Point
def bottomRight: Point
def left = topLeft.x
def right = bottomRight.x
def width = right - left
// and many more geometric methods...
}
abstract class Component extends Rectangular {
// other methods...
}
class Rectangle(val topLeft: Point, val bottomRight: Point)
extends Rectangular {
// other methods...
}
scala> val rect = new Rectangle(new Point(1, 1),
new Point(10, 10))
rect: Rectangle = Rectangle@3536fd
scala> rect.left
res2: Int = 1
scala> rect.right
res3: Int = 10
Rectangular objects with traits
class Rational(n: Int, d: Int) {
// ...
def <(that: Rational) =
this.numer * that.denom > that.numer * this.denom
def >(that: Rational) = that < this
def <=(that: Rational) = (this < that) || (this == that)
def >=(that: Rational) = (this > that) || (this == that)
}
defined in terms of <
based on standard
semantics of ordering
{
A Rich Interface for Ordering
class Rational(n: Int, d: Int) {
// ...
def <(that: Rational) =
this.numer * that.denom > that.numer * this.denom
def >(that: Rational) = that < this
def <=(that: Rational) = (this < that) || (this == that)
def >=(that: Rational) = (this > that) || (this == that)
}
defined in terms of <
based on standard
semantics of ordering
{
class Rational(n: Int, d: Int) extends Ordered[Rational] {
// ...
def compare(that: Rational) =
(this.numer * that.denom) - (that.numer * this.denom)
}
A Rich Interface for Ordering
class Rational(n: Int, d: Int) {
// ...
def <(that: Rational) =
this.numer * that.denom > that.numer * this.denom
def >(that: Rational) = that < this
def <=(that: Rational) = (this < that) || (this == that)
def >=(that: Rational) = (this > that) || (this == that)
}
defined in terms of <
based on standard
semantics of ordering
{
class Rational(n: Int, d: Int) extends Ordered[Rational] {
// ...
def compare(that: Rational) =
(this.numer * that.denom) - (that.numer * this.denom)
}
Ordered trait provides reusable
implementation of ordering
A Rich Interface for Ordering
Class Queue of integers
• put: place integer in queue
• get: take integer out
• first-in first-out
Modifications
• Doubling: double all integers put in queue
• Incrementing: increment all integers put in queue
• Filtering: filter out negative
Stackable Modifications
abstract class IntQueue {
def get(): Int
def put(x: Int)
}
import scala.collection.mutable.ArrayBuffer
class BasicIntQueue extends IntQueue {
private val buf = new ArrayBuffer[Int]
def get() = buf.remove(0)
def put(x: Int) { buf += x }
}
Class Queue
abstract class IntQueue {
def get(): Int
def put(x: Int)
}
import scala.collection.mutable.ArrayBuffer
class BasicIntQueue extends IntQueue {
private val buf = new ArrayBuffer[Int]
def get() = buf.remove(0)
def put(x: Int) { buf += x }
}
scala> val queue = new BasicIntQueue
queue: BasicIntQueue = BasicIntQueue@24655f
scala> queue.put(10)
scala> queue.put(20)
scala> queue.get()
res9: Int = 10
scala> queue.get()
res10: Int = 20
Class Queue
trait Doubling extends IntQueue {
abstract override def put(x: Int) { super.put(2 * x) }
}
dynamically bound
can only be mixed into
subclasses of IntQueue
mix into class
with concrete
definition
Trait Doubling
trait Doubling extends IntQueue {
abstract override def put(x: Int) { super.put(2 * x) }
}
dynamically bound
can only be mixed into
subclasses of IntQueue
mix into class
with concrete
definition
scala> class MyQueue extends BasicIntQueue with Doubling
defined class MyQueue
scala> val queue = new MyQueue
queue: MyQueue = MyQueue@91f017
scala> queue.put(10)
scala> queue.get()
res12: Int = 20
Trait Doubling
trait Doubling extends IntQueue {
abstract override def put(x: Int) { super.put(2 * x) }
}
dynamically bound
can only be mixed into
subclasses of IntQueue
mix into class
with concrete
definition
scala> class MyQueue extends BasicIntQueue with Doubling
defined class MyQueue
scala> val queue = new MyQueue
queue: MyQueue = MyQueue@91f017
scala> queue.put(10)
scala> queue.get()
res12: Int = 20
scala> val queue = new BasicIntQueue with Doubling
queue: BasicIntQueue with Doubling = $anon$1@5fa12d
scala> queue.put(10)
scala> queue.get()
res14: Int = 20
Trait Doubling
trait Incrementing extends IntQueue {
abstract override def put(x: Int) { super.put(x + 1) }
}
trait Filtering extends IntQueue {
abstract override def put(x: Int) {
if (x >= 0) super.put(x)
}
}
Stacking Modifications
trait Incrementing extends IntQueue {
abstract override def put(x: Int) { super.put(x + 1) }
}
trait Filtering extends IntQueue {
abstract override def put(x: Int) {
if (x >= 0) super.put(x)
}
}
scala> val queue = (new BasicIntQueue
with Incrementing
with Filtering)
scala> queue.put(-1);
queue.put(0);
queue.put(1)
scala> queue.get()
res15: Int = 1
scala> queue.get()
res15: Int = 2
Stacking Modifications
trait Incrementing extends IntQueue {
abstract override def put(x: Int) { super.put(x + 1) }
}
trait Filtering extends IntQueue {
abstract override def put(x: Int) {
if (x >= 0) super.put(x)
}
}
scala> val queue = (new BasicIntQueue
with Incrementing
with Filtering)
scala> queue.put(-1);
queue.put(0);
queue.put(1)
scala> queue.get()
res15: Int = 1
scala> queue.get()
res15: Int = 2
Stacking Modifications
scala> val queue = (new BasicIntQueue
with Filtering
with Incrementing)
scala> queue.put(-1);
queue.put(0);
queue.put(1)
scala> queue.get()
res17: Int = 0
scala> queue.get()
res18: Int = 1
scala> queue.get()
res19: Int = 2
// Multiple inheritance thought experiment
val q = new BasicIntQueue with Incrementing with Doubling
q.put(42) // which put would be called?
Multiple Inheritance (Why Not?)
Incrementing Doubling
BasicIntQueue
new BasicIntQueue with
Increment with Doubling
// Multiple inheritance thought experiment
trait MyQueue extends BasicIntQueue
with Incrementing with Doubling {
def put(x: Int) {
Incrementing.super.put(x)
// (Not real Scala)
Doubling.super.put(x)
}
}
Multiple Inheritance (Why Not?)
Incrementing Doubling
BasicIntQueue
new BasicIntQueue with
Increment with Doubling
put of BasicIntQue
called twice!
a class is always linearized before all
of its superclasses and mixed in traits
class Animal
trait Furry extends Animal
trait HasLegs extends Animal
trait FourLegged extends HasLegs
class Cat extends Animal with Furry with FourLegged
Linearly Ordering Traits
Units of code
• reusable through inheritance
• can be mixed in at multiple places in hierarchy
Multiple inheritance ++
• calls to super are linearized
• avoid diamond problem
• stack changes
Traits Summary
What is the value of question in:
class Animal {
override def toString = "Animal"
}
trait Furry extends Animal {
override def toString = "Furry -> " + super.toString
}
trait HasLegs extends Animal {
override def toString = "HasLegs -> " + super.toString
}
trait FourLegged extends HasLegs {
override def toString = "FourLegged -> " + super.toString
}
class Cat extends Animal with Furry with FourLegged {
override def toString = "Cat -> " + super.toString
}
val question = new Cat
a) Cat -> FourLegged -> HasLegs -> Furry -> Animal
b) Cat -> HasLegs -> FourLegged -> Furry -> Animal
c) Cat -> Furry -> FourLegged -> HasLegs -> Animal
d) Cat -> Furry -> HasLegs -> FourLegged -> Animal
Traits Experiment
Type Parameterization
def append[T](xs: List[T], ys: List[T]): List[T] =
xs match {
case List() => ys
case x :: xs1 => x :: append(xs1, ys)
}
def map[A,B](xs: List[A], f: A => B): List[B] = xs match {
case List() => List()
case y :: ys => f(y) :: map(ys, f)
}
Generic classes and traits
• Set[T]: generic sets parameterized with type T
• Set[Int]: set of integers, instance of Set[T]
• No raw types: always use with type parameter
Example: Functional Queues
typedef struct queue_elem {
int val;
struct queue_elem *next;
} queue_elem;
typedef struct queue {
queue_elem *first;
queue_elem *last;
} queue;
queue *newQueue() {
queue *q = (queue *)malloc(sizeof(queue));
q->first = NULL;
q->last = NULL;
return q;
}
Imperative Queue in C
void enqueue(queue *q, int val) {
queue_elem *elem = (queue_elem *)malloc(sizeof(queue_elem));
elem->val = val;
elem->next = NULL;
if(q->first == NULL) {
q->first = q->last = elem;
} else {
q->last->next = elem;
q->last = elem;
}
}
Imperative Queue in C
int dequeue(queue *q) {
if(q == NULL || q->first == NULL) {
return 0;
}
int val = q->first->val;
queue_elem *elem = q->first;
if(q->first == q->last) {
q->last = NULL;
}
q->first = q->first->next;
free(elem);
return val;
}
Imperative Queue in C
Queue operations
• head: return first element
• tail: return rest
• append: new queue with new element at the end
Functional Queue
• fully persistent
• contents not changed when appending
• efficient implementation should be O(1) for all operations
scala> val q = Queue(1, 2, 3)
q: Queue[Int] = Queue(1, 2, 3)
scala> val q1 = q append 4
q1: Queue[Int] = Queue(1, 2, 3, 4)
scala> q
res0: Queue[Int] = Queue(1, 2, 3)
Functional Queue
class SlowAppendQueue[T](elems: List[T]) { // Not efficient
def head = elems.head
def tail = new SlowAppendQueue(elems.tail)
def append(x: T) = new SlowAppendQueue(elems ::: List(x))
}
Functional Queue (First Attempt)
class SlowAppendQueue[T](elems: List[T]) { // Not efficient
def head = elems.head
def tail = new SlowAppendQueue(elems.tail)
def append(x: T) = new SlowAppendQueue(elems ::: List(x))
}
append = O(n)
Functional Queue (First Attempt)
class SlowAppendQueue[T](elems: List[T]) { // Not efficient
def head = elems.head
def tail = new SlowAppendQueue(elems.tail)
def append(x: T) = new SlowAppendQueue(elems ::: List(x))
}
class SlowHeadQueue[T](smele: List[T]) { // Not efficient
// smele is elems reversed
def head = smele.last
def tail = new SlowHeadQueue(smele.init)
def append(x: T) = new SlowHeadQueue(x :: smele)
}
append = O(n)
Functional Queue (First Attempt)
class SlowAppendQueue[T](elems: List[T]) { // Not efficient
def head = elems.head
def tail = new SlowAppendQueue(elems.tail)
def append(x: T) = new SlowAppendQueue(elems ::: List(x))
}
class SlowHeadQueue[T](smele: List[T]) { // Not efficient
// smele is elems reversed
def head = smele.last
def tail = new SlowHeadQueue(smele.init)
def append(x: T) = new SlowHeadQueue(x :: smele)
}
append = O(n)
head, tail = O(n)
Functional Queue (First Attempt)
class SlowAppendQueue[T](elems: List[T]) { // Not efficient
def head = elems.head
def tail = new SlowAppendQueue(elems.tail)
def append(x: T) = new SlowAppendQueue(elems ::: List(x))
}
class SlowHeadQueue[T](smele: List[T]) { // Not efficient
// smele is elems reversed
def head = smele.last
def tail = new SlowHeadQueue(smele.init)
def append(x: T) = new SlowHeadQueue(x :: smele)
}
append = O(n)
head, tail = O(n)
head, tail, append = O(1) cannot be possible!
Functional Queue (First Attempt)
class Queue[T](
private val leading: List[T],
private val trailing: List[T]
) {
def head = leading.head
def tail = new Queue(leading.tail, trailing)
def append(x: T) = new Queue(leading, x :: trailing)
}
elems == leading ::: trailing.reverse
Represent Queue with Two Lists
class Queue[T](
private val leading: List[T],
private val trailing: List[T]
) {
def head = leading.head
def tail = new Queue(leading.tail, trailing)
def append(x: T) = new Queue(leading, x :: trailing)
}
elems == leading ::: trailing.reverse
but what if leading.isEmpty?
Represent Queue with Two Lists
Mirroring
class Queue[T](
private val leading: List[T],
private val trailing: List[T]
) {
private def mirror =
if (leading.isEmpty)
new Queue(trailing.reverse, Nil)
else
this
def head = mirror.leading.head
def tail = {
val q = mirror
new Queue(q.leading.tail, q.trailing)
}
def append(x: T) =
new Queue(leading, x :: trailing)
}
Mirroring
class Queue[T](
private val leading: List[T],
private val trailing: List[T]
) {
private def mirror =
if (leading.isEmpty)
new Queue(trailing.reverse, Nil)
else
this
def head = mirror.leading.head
def tail = {
val q = mirror
new Queue(q.leading.tail, q.trailing)
}
def append(x: T) =
new Queue(leading, x :: trailing)
}
head, tail, append: O(1)
mirror: O(n)
but amortized over n calls of tail
Mirroring
class Queue[T](
private val leading: List[T],
private val trailing: List[T]
) {
private def mirror =
if (leading.isEmpty)
new Queue(trailing.reverse, Nil)
else
this
def head = mirror.leading.head
def tail = {
val q = mirror
new Queue(q.leading.tail, q.trailing)
}
def append(x: T) =
new Queue(leading, x :: trailing)
}
head, tail, append: O(1)
mirror: O(n)
but amortized over n calls of tail
implementation is exposed!
class Queue[T] private (
private val leading: List[T],
private val trailing: List[T]
) {
def this() = this(Nil, Nil)
def this(elems: T*) = this(elems.toList, Nil)
def head = ...
def tail = ...
def append(x: T) = ...
}
scala> Queue(1, 2, 3)
private parameters
public auxiliary constructors
hide implementation
details from clients
Private Constructors
class Queue[T] private (
private val leading: List[T],
private val trailing: List[T]
) {
def head = ...
def tail = ...
def append(x: T) = ...
}
object Queue {
// constructs a queue with initial elements ‘xs’
def apply[T](xs: T*) = new Queue[T](xs.toList, Nil)
}
Factory Method hide implementation
details from clients
factory method
private parameters
trait Queue[T] {
def head: T
def tail: Queue[T]
def append(x: T): Queue[T]
}
object Queue {
def apply[T](xs: T*): Queue[T] = new QueueImpl[T](xs.toList, Nil)
private class QueueImpl[T](
private val leading: List[T],
private val trailing: List[T]
) extends Queue[T] {
def mirror =
if (leading.isEmpty) new QueueImpl(trailing.reverse, Nil)
else this
def head: T = mirror.leading.head
def tail: QueueImpl[T] = {
val q = mirror
new QueueImpl(q.leading.tail, q.trailing)
}
def append(x: T) = new QueueImpl(leading, x :: trailing)
}
}
hide implementation
details from clients
scala> def doesNotCompile(q: Queue) {}
<console>:5: error: trait Queue takes type parameters
def doesNotCompile(q: Queue) {}
scala> def doesCompile(q: Queue[AnyRef]) {}
doesCompile: (Queue[AnyRef])Unit
Queue is a trait, not a type
Queue is a type constructor or generic trait
Queue[String] is a (specific) type
Generic Traits
Queue[String] subtype of Queue[AnyRef] ?
if S subtype of T then Queue[S] subtype of Queue[T] ?
If answer is yes: Queue is covariant in T
trait Queue[+T] { ... }
val q: Queue[AnyRef] = Queue[String](“a”)
If answer is no: Queue is contravariant in T
trait Queue[-T] { ... }
val q: Queue[String] = Queue[AnyRef]()default: nonvariant
Subtyping &Variance Annotations
class Cell[+T](init: T) {
private[this] var current = init
def get = current
def set(x: T) { current = x }
}
val c1 = new Cell[String]("abc")
val c2: Cell[Any] = c1
c2.set(1)
val s: String = c1.get
Covariance and Mutable Classes
class Cell[+T](init: T) {
private[this] var current = init
def get = current
def set(x: T) { current = x }
}
val c1 = new Cell[String]("abc")
val c2: Cell[Any] = c1
c2.set(1)
val s: String = c1.get
Cell.scala:7: error: covariant type T occurs in
contravariant position in type T of value x
def set(x: T) = current = x
Covariance and Mutable Classes
package society {
package professional {
class Executive {
private[professional] var workDetails = null
private[society] var friends = null
private[this] var secrets = null
def help(another : Executive) {
println(another.workDetails)
println(another.secrets) //ERROR
}
}
}
}
Source: http://www.tutorialspoint.com/scala/scala_access_modifiers.htm
Scope of Protection of Access Modifiers
A private member is visible only inside the class or object that contains the member definition.
A protected member is only accessible from subclasses of the class in which the member is defined.
Every member not labeled private or protected is public. There is no explicit modifier for public members.
Such members can be accessed from anywhere.
// this is Java
String[] a1 = { "abc" };
Object[] a2 = a1;
a2[0] = new Integer(17);
String s = a1[0];
no compile-time error
Variance and Arrays
// this is Java
String[] a1 = { "abc" };
Object[] a2 = a1;
a2[0] = new Integer(17);
String s = a1[0];
Exception in thread "main" java.lang.ArrayStoreException:
java.lang.Integer at JavaArrays.main(JavaArrays.java:8)
no compile-time error
Variance and Arrays
// this is Java
String[] a1 = { "abc" };
Object[] a2 = a1;
a2[0] = new Integer(17);
String s = a1[0];
Exception in thread "main" java.lang.ArrayStoreException:
java.lang.Integer at JavaArrays.main(JavaArrays.java:8)
no compile-time error
motivation: generic treatment of arrays:
void sort(Object[] a, Comparator cmp) { ... }
Variance and Arrays
scala> val a1 = Array("abc")
a1: Array[java.lang.String] = Array(abc)
scala> val a2: Array[Any] = a1
<console>:5: error: type mismatch;
found : Array[java.lang.String]
required: Array[Any]
val a2: Array[Any] = a1
ˆ
scala> val a2: Array[Object] =
a1.asInstanceOf[Array[Object]]
a2: Array[java.lang.Object] = Array(abc)
Scala Arrays are Non-variant
class Queue[+T] {
def append(x: T) =
...
}
class StrangeIntQueue extends Queue[Int] {
override def append(x: Int) = {
println(Math.sqrt(x))
super.append(x)
}
}
val x: Queue[Any] = new StrangeIntQueue
x.append("abc")
CheckingVariance Annotations
class Queue[+T] {
def append(x: T) =
...
}
class StrangeIntQueue extends Queue[Int] {
override def append(x: Int) = {
println(Math.sqrt(x))
super.append(x)
}
}
val x: Queue[Any] = new StrangeIntQueue
x.append("abc")
Queues.scala:11: error: covariant type T occurs in
contravariant position in type T of value x
def append(x: T) =
ˆ
CheckingVariance Annotations
class Queue[+T](
private val leading: List[T],
private val trailing: List[T]
) {
def append[U >: T](x: U) =
new Queue[U](leading, x :: trailing) // ...
}
class Fruit
class Apple extends Fruit
class Orange extends Fruit
scala> val qa = Queue(new Apple)
scala> val qb = qa.append(new Orange)
qb: Queue[Fruit] = ...
U >: T == U is a supertype of T
Lower Bounds
class Queue[+T] private (
private[this] var leading: List[T],
private[this] var trailing: List[T]
) {
private def mirror() =
if (leading.isEmpty) {
while (!trailing.isEmpty) {
leading = trailing.head :: leading
trailing = trailing.tail
}
}
def head: T = {
mirror(); leading.head
}
def tail: Queue[T] = {
mirror();
new Queue(leading.tail, trailing)
}
def append[U >: T](x: U) =
new Queue[U](leading, x :: trailing)
}
Optimized Functional Queue
def orderedMergeSort[T <: Ordered[T]](xs: List[T]): List[T] = {
def merge(xs: List[T], ys: List[T]): List[T] =
(xs, ys) match {
case (Nil, _) => ys
case (_, Nil) => xs
case (x :: xs1, y :: ys1) =>
if (x < y) x :: merge(xs1, ys)
else y :: merge(xs, ys1)
}
val n = xs.length / 2
if (n == 0) xs
else {
val (ys, zs) = xs splitAt n
merge(orderedMergeSort(ys), orderedMergeSort(zs))
}
}
Upperbounds
Information hiding
• private constructors
• factory methods
• object private members
Type variance
• subtyping of generic types
• covariant, contravariant variance annotations
• lower bounds, upper bounds
Type Parameterization Summary
Reading & Programming in Week 6
Reading
Scala Chapter 12: Traits
Scala Chapter 19: Type Parameterization
Week 9: Parsers and Interpreters
WebLab:
Graded Assignment 2: (deadline 14 May 2013, 23:59)

Más contenido relacionado

La actualidad más candente

JBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java ProgrammersJBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java ProgrammersTikal Knowledge
 
Scala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesTomer Gabel
 
Scala collections api expressivity and brevity upgrade from java
Scala collections api  expressivity and brevity upgrade from javaScala collections api  expressivity and brevity upgrade from java
Scala collections api expressivity and brevity upgrade from javaIndicThreads
 
Data structures in scala
Data structures in scalaData structures in scala
Data structures in scalaMeetu Maltiar
 
Introduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskellnebuta
 
R reference card
R reference cardR reference card
R reference cardHesher Shih
 
Scala基礎勉強会: Featherweight Scalaの紹介および型付け規則の決定可能性について
Scala基礎勉強会: Featherweight Scalaの紹介および型付け規則の決定可能性についてScala基礎勉強会: Featherweight Scalaの紹介および型付け規則の決定可能性について
Scala基礎勉強会: Featherweight Scalaの紹介および型付け規則の決定可能性についてHiroki Mizuno
 
Lec 8 03_sept [compatibility mode]
Lec 8 03_sept [compatibility mode]Lec 8 03_sept [compatibility mode]
Lec 8 03_sept [compatibility mode]Palak Sanghani
 
Data Structures In Scala
Data Structures In ScalaData Structures In Scala
Data Structures In ScalaKnoldus Inc.
 
R Reference Card for Data Mining
R Reference Card for Data MiningR Reference Card for Data Mining
R Reference Card for Data MiningYanchang Zhao
 
R short-refcard
R short-refcardR short-refcard
R short-refcardconline
 

La actualidad más candente (16)

Scala collection
Scala collectionScala collection
Scala collection
 
JBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java ProgrammersJBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java Programmers
 
Scala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type Classes
 
Scala collections api expressivity and brevity upgrade from java
Scala collections api  expressivity and brevity upgrade from javaScala collections api  expressivity and brevity upgrade from java
Scala collections api expressivity and brevity upgrade from java
 
Data structures in scala
Data structures in scalaData structures in scala
Data structures in scala
 
Scala for curious
Scala for curiousScala for curious
Scala for curious
 
Introduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskell
 
R reference card
R reference cardR reference card
R reference card
 
Scala collections
Scala collectionsScala collections
Scala collections
 
Core C#
Core C#Core C#
Core C#
 
Scala基礎勉強会: Featherweight Scalaの紹介および型付け規則の決定可能性について
Scala基礎勉強会: Featherweight Scalaの紹介および型付け規則の決定可能性についてScala基礎勉強会: Featherweight Scalaの紹介および型付け規則の決定可能性について
Scala基礎勉強会: Featherweight Scalaの紹介および型付け規則の決定可能性について
 
Lec 8 03_sept [compatibility mode]
Lec 8 03_sept [compatibility mode]Lec 8 03_sept [compatibility mode]
Lec 8 03_sept [compatibility mode]
 
Frp2016 3
Frp2016 3Frp2016 3
Frp2016 3
 
Data Structures In Scala
Data Structures In ScalaData Structures In Scala
Data Structures In Scala
 
R Reference Card for Data Mining
R Reference Card for Data MiningR Reference Card for Data Mining
R Reference Card for Data Mining
 
R short-refcard
R short-refcardR short-refcard
R short-refcard
 

Destacado

Java 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardJava 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardMario Fusco
 
Introducing Drools
Introducing DroolsIntroducing Drools
Introducing DroolsMario Fusco
 
OOP and FP - Become a Better Programmer
OOP and FP - Become a Better ProgrammerOOP and FP - Become a Better Programmer
OOP and FP - Become a Better ProgrammerMario Fusco
 
Real world DSL - making technical and business people speaking the same language
Real world DSL - making technical and business people speaking the same languageReal world DSL - making technical and business people speaking the same language
Real world DSL - making technical and business people speaking the same languageMario Fusco
 
Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Mario Fusco
 
Drools 6 deep dive
Drools 6 deep diveDrools 6 deep dive
Drools 6 deep diveMario Fusco
 

Destacado (7)

Java 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardJava 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forward
 
Introducing Drools
Introducing DroolsIntroducing Drools
Introducing Drools
 
Java 8 Workshop
Java 8 WorkshopJava 8 Workshop
Java 8 Workshop
 
OOP and FP - Become a Better Programmer
OOP and FP - Become a Better ProgrammerOOP and FP - Become a Better Programmer
OOP and FP - Become a Better Programmer
 
Real world DSL - making technical and business people speaking the same language
Real world DSL - making technical and business people speaking the same languageReal world DSL - making technical and business people speaking the same language
Real world DSL - making technical and business people speaking the same language
 
Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...
 
Drools 6 deep dive
Drools 6 deep diveDrools 6 deep dive
Drools 6 deep dive
 

Similar a TI1220 Lecture 8: Traits & Type Parameterization

Inheritance And Traits
Inheritance And TraitsInheritance And Traits
Inheritance And TraitsPiyush Mishra
 
Lecture 5: Functional Programming
Lecture 5: Functional ProgrammingLecture 5: Functional Programming
Lecture 5: Functional ProgrammingEelco Visser
 
The Scala Programming Language
The Scala Programming LanguageThe Scala Programming Language
The Scala Programming Languageleague
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
Functional programming with Scala
Functional programming with ScalaFunctional programming with Scala
Functional programming with ScalaNeelkanth Sachdeva
 
Functional Programming With Scala
Functional Programming With ScalaFunctional Programming With Scala
Functional Programming With ScalaKnoldus Inc.
 
Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009Martin Odersky
 
Scala for Java Programmers
Scala for Java ProgrammersScala for Java Programmers
Scala for Java ProgrammersEric Pederson
 
From Java to Scala - advantages and possible risks
From Java to Scala - advantages and possible risksFrom Java to Scala - advantages and possible risks
From Java to Scala - advantages and possible risksSeniorDevOnly
 

Similar a TI1220 Lecture 8: Traits & Type Parameterization (20)

Inheritance And Traits
Inheritance And TraitsInheritance And Traits
Inheritance And Traits
 
Traits inscala
Traits inscalaTraits inscala
Traits inscala
 
Lecture 5: Functional Programming
Lecture 5: Functional ProgrammingLecture 5: Functional Programming
Lecture 5: Functional Programming
 
The Scala Programming Language
The Scala Programming LanguageThe Scala Programming Language
The Scala Programming Language
 
Lecture 3
Lecture 3Lecture 3
Lecture 3
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
scala.ppt
scala.pptscala.ppt
scala.ppt
 
Scala - brief intro
Scala - brief introScala - brief intro
Scala - brief intro
 
Functional object
Functional objectFunctional object
Functional object
 
Scala
ScalaScala
Scala
 
Functional programming with Scala
Functional programming with ScalaFunctional programming with Scala
Functional programming with Scala
 
Functional Programming With Scala
Functional Programming With ScalaFunctional Programming With Scala
Functional Programming With Scala
 
Spark workshop
Spark workshopSpark workshop
Spark workshop
 
C# programming
C# programming C# programming
C# programming
 
Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009
 
Scala for Java Programmers
Scala for Java ProgrammersScala for Java Programmers
Scala for Java Programmers
 
From Java to Scala - advantages and possible risks
From Java to Scala - advantages and possible risksFrom Java to Scala - advantages and possible risks
From Java to Scala - advantages and possible risks
 

Más de Eelco Visser

CS4200 2019 | Lecture 5 | Transformation by Term Rewriting
CS4200 2019 | Lecture 5 | Transformation by Term RewritingCS4200 2019 | Lecture 5 | Transformation by Term Rewriting
CS4200 2019 | Lecture 5 | Transformation by Term RewritingEelco Visser
 
CS4200 2019 | Lecture 4 | Syntactic Services
CS4200 2019 | Lecture 4 | Syntactic ServicesCS4200 2019 | Lecture 4 | Syntactic Services
CS4200 2019 | Lecture 4 | Syntactic ServicesEelco Visser
 
CS4200 2019 | Lecture 3 | Parsing
CS4200 2019 | Lecture 3 | ParsingCS4200 2019 | Lecture 3 | Parsing
CS4200 2019 | Lecture 3 | ParsingEelco Visser
 
CS4200 2019 | Lecture 2 | syntax-definition
CS4200 2019 | Lecture 2 | syntax-definitionCS4200 2019 | Lecture 2 | syntax-definition
CS4200 2019 | Lecture 2 | syntax-definitionEelco Visser
 
CS4200 2019 Lecture 1: Introduction
CS4200 2019 Lecture 1: IntroductionCS4200 2019 Lecture 1: Introduction
CS4200 2019 Lecture 1: IntroductionEelco Visser
 
A Direct Semantics of Declarative Disambiguation Rules
A Direct Semantics of Declarative Disambiguation RulesA Direct Semantics of Declarative Disambiguation Rules
A Direct Semantics of Declarative Disambiguation RulesEelco Visser
 
Declarative Type System Specification with Statix
Declarative Type System Specification with StatixDeclarative Type System Specification with Statix
Declarative Type System Specification with StatixEelco Visser
 
Compiler Construction | Lecture 17 | Beyond Compiler Construction
Compiler Construction | Lecture 17 | Beyond Compiler ConstructionCompiler Construction | Lecture 17 | Beyond Compiler Construction
Compiler Construction | Lecture 17 | Beyond Compiler ConstructionEelco Visser
 
Domain Specific Languages for Parallel Graph AnalytiX (PGX)
Domain Specific Languages for Parallel Graph AnalytiX (PGX)Domain Specific Languages for Parallel Graph AnalytiX (PGX)
Domain Specific Languages for Parallel Graph AnalytiX (PGX)Eelco Visser
 
Compiler Construction | Lecture 15 | Memory Management
Compiler Construction | Lecture 15 | Memory ManagementCompiler Construction | Lecture 15 | Memory Management
Compiler Construction | Lecture 15 | Memory ManagementEelco Visser
 
Compiler Construction | Lecture 14 | Interpreters
Compiler Construction | Lecture 14 | InterpretersCompiler Construction | Lecture 14 | Interpreters
Compiler Construction | Lecture 14 | InterpretersEelco Visser
 
Compiler Construction | Lecture 13 | Code Generation
Compiler Construction | Lecture 13 | Code GenerationCompiler Construction | Lecture 13 | Code Generation
Compiler Construction | Lecture 13 | Code GenerationEelco Visser
 
Compiler Construction | Lecture 12 | Virtual Machines
Compiler Construction | Lecture 12 | Virtual MachinesCompiler Construction | Lecture 12 | Virtual Machines
Compiler Construction | Lecture 12 | Virtual MachinesEelco Visser
 
Compiler Construction | Lecture 11 | Monotone Frameworks
Compiler Construction | Lecture 11 | Monotone FrameworksCompiler Construction | Lecture 11 | Monotone Frameworks
Compiler Construction | Lecture 11 | Monotone FrameworksEelco Visser
 
Compiler Construction | Lecture 10 | Data-Flow Analysis
Compiler Construction | Lecture 10 | Data-Flow AnalysisCompiler Construction | Lecture 10 | Data-Flow Analysis
Compiler Construction | Lecture 10 | Data-Flow AnalysisEelco Visser
 
Compiler Construction | Lecture 9 | Constraint Resolution
Compiler Construction | Lecture 9 | Constraint ResolutionCompiler Construction | Lecture 9 | Constraint Resolution
Compiler Construction | Lecture 9 | Constraint ResolutionEelco Visser
 
Compiler Construction | Lecture 8 | Type Constraints
Compiler Construction | Lecture 8 | Type ConstraintsCompiler Construction | Lecture 8 | Type Constraints
Compiler Construction | Lecture 8 | Type ConstraintsEelco Visser
 
Compiler Construction | Lecture 7 | Type Checking
Compiler Construction | Lecture 7 | Type CheckingCompiler Construction | Lecture 7 | Type Checking
Compiler Construction | Lecture 7 | Type CheckingEelco Visser
 
Compiler Construction | Lecture 6 | Introduction to Static Analysis
Compiler Construction | Lecture 6 | Introduction to Static AnalysisCompiler Construction | Lecture 6 | Introduction to Static Analysis
Compiler Construction | Lecture 6 | Introduction to Static AnalysisEelco Visser
 
Compiler Construction | Lecture 5 | Transformation by Term Rewriting
Compiler Construction | Lecture 5 | Transformation by Term RewritingCompiler Construction | Lecture 5 | Transformation by Term Rewriting
Compiler Construction | Lecture 5 | Transformation by Term RewritingEelco Visser
 

Más de Eelco Visser (20)

CS4200 2019 | Lecture 5 | Transformation by Term Rewriting
CS4200 2019 | Lecture 5 | Transformation by Term RewritingCS4200 2019 | Lecture 5 | Transformation by Term Rewriting
CS4200 2019 | Lecture 5 | Transformation by Term Rewriting
 
CS4200 2019 | Lecture 4 | Syntactic Services
CS4200 2019 | Lecture 4 | Syntactic ServicesCS4200 2019 | Lecture 4 | Syntactic Services
CS4200 2019 | Lecture 4 | Syntactic Services
 
CS4200 2019 | Lecture 3 | Parsing
CS4200 2019 | Lecture 3 | ParsingCS4200 2019 | Lecture 3 | Parsing
CS4200 2019 | Lecture 3 | Parsing
 
CS4200 2019 | Lecture 2 | syntax-definition
CS4200 2019 | Lecture 2 | syntax-definitionCS4200 2019 | Lecture 2 | syntax-definition
CS4200 2019 | Lecture 2 | syntax-definition
 
CS4200 2019 Lecture 1: Introduction
CS4200 2019 Lecture 1: IntroductionCS4200 2019 Lecture 1: Introduction
CS4200 2019 Lecture 1: Introduction
 
A Direct Semantics of Declarative Disambiguation Rules
A Direct Semantics of Declarative Disambiguation RulesA Direct Semantics of Declarative Disambiguation Rules
A Direct Semantics of Declarative Disambiguation Rules
 
Declarative Type System Specification with Statix
Declarative Type System Specification with StatixDeclarative Type System Specification with Statix
Declarative Type System Specification with Statix
 
Compiler Construction | Lecture 17 | Beyond Compiler Construction
Compiler Construction | Lecture 17 | Beyond Compiler ConstructionCompiler Construction | Lecture 17 | Beyond Compiler Construction
Compiler Construction | Lecture 17 | Beyond Compiler Construction
 
Domain Specific Languages for Parallel Graph AnalytiX (PGX)
Domain Specific Languages for Parallel Graph AnalytiX (PGX)Domain Specific Languages for Parallel Graph AnalytiX (PGX)
Domain Specific Languages for Parallel Graph AnalytiX (PGX)
 
Compiler Construction | Lecture 15 | Memory Management
Compiler Construction | Lecture 15 | Memory ManagementCompiler Construction | Lecture 15 | Memory Management
Compiler Construction | Lecture 15 | Memory Management
 
Compiler Construction | Lecture 14 | Interpreters
Compiler Construction | Lecture 14 | InterpretersCompiler Construction | Lecture 14 | Interpreters
Compiler Construction | Lecture 14 | Interpreters
 
Compiler Construction | Lecture 13 | Code Generation
Compiler Construction | Lecture 13 | Code GenerationCompiler Construction | Lecture 13 | Code Generation
Compiler Construction | Lecture 13 | Code Generation
 
Compiler Construction | Lecture 12 | Virtual Machines
Compiler Construction | Lecture 12 | Virtual MachinesCompiler Construction | Lecture 12 | Virtual Machines
Compiler Construction | Lecture 12 | Virtual Machines
 
Compiler Construction | Lecture 11 | Monotone Frameworks
Compiler Construction | Lecture 11 | Monotone FrameworksCompiler Construction | Lecture 11 | Monotone Frameworks
Compiler Construction | Lecture 11 | Monotone Frameworks
 
Compiler Construction | Lecture 10 | Data-Flow Analysis
Compiler Construction | Lecture 10 | Data-Flow AnalysisCompiler Construction | Lecture 10 | Data-Flow Analysis
Compiler Construction | Lecture 10 | Data-Flow Analysis
 
Compiler Construction | Lecture 9 | Constraint Resolution
Compiler Construction | Lecture 9 | Constraint ResolutionCompiler Construction | Lecture 9 | Constraint Resolution
Compiler Construction | Lecture 9 | Constraint Resolution
 
Compiler Construction | Lecture 8 | Type Constraints
Compiler Construction | Lecture 8 | Type ConstraintsCompiler Construction | Lecture 8 | Type Constraints
Compiler Construction | Lecture 8 | Type Constraints
 
Compiler Construction | Lecture 7 | Type Checking
Compiler Construction | Lecture 7 | Type CheckingCompiler Construction | Lecture 7 | Type Checking
Compiler Construction | Lecture 7 | Type Checking
 
Compiler Construction | Lecture 6 | Introduction to Static Analysis
Compiler Construction | Lecture 6 | Introduction to Static AnalysisCompiler Construction | Lecture 6 | Introduction to Static Analysis
Compiler Construction | Lecture 6 | Introduction to Static Analysis
 
Compiler Construction | Lecture 5 | Transformation by Term Rewriting
Compiler Construction | Lecture 5 | Transformation by Term RewritingCompiler Construction | Lecture 5 | Transformation by Term Rewriting
Compiler Construction | Lecture 5 | Transformation by Term Rewriting
 

Último

presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusZilliz
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...apidays
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 

Último (20)

presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 

TI1220 Lecture 8: Traits & Type Parameterization

  • 1. TI1220 2012-2013 Concepts of Programming Languages Eelco Visser / TU Delft Lecture 8: Traits & Type Parameterization
  • 2. var ms := course.managers; var ms : Set<Person> := Set<Person>(); ms.addAll(course.managers); Analysis => Lecture 12: Concurrency Root Cause The Fix Intention: copy semantics Effect: reference semantics The Fault: Concurrent writes on CourseEdition
  • 4. Syntax and Semantics Names, Bindings, and Scopes Storage Data Types Functional Programming First-class Functions Polymorphism Traits & Type Parameterization Parsing and Interpretation Data Abstraction / Modular Programming Functional Programming Redux Concurrency Concurrent Programming Domain-Specific Languages Quarter 3 Quarter 4 Basics of Scala JavaScript C
  • 6. abstract class Element { def contents: Array[String] def height: Int = contents.length def width: Int = if (height == 0) 0 else contents(0).length } class ArrayElement(conts: Array[String]) extends Element { val contents: Array[String] = conts } Classical Inheritance Inheriting fields and methods
  • 7. class UniformElement( ch: Char, override val width: Int, override val height: Int ) extends Element { private val line = ch.toString * width def contents = Array.make(height, line) } val e1: Element = new ArrayElement(Array("hello", "world")) val ae: ArrayElement = new LineElement("hello") val e2: Element = ae val e3: Element = new UniformElement('x', 2, 3) Subtyping
  • 8. abstract class Element { def demo() { println("Element's implementation invoked") } } class ArrayElement extends Element { override def demo() { println("ArrayElement's implementation invoked") } } class LineElement extends ArrayElement { override def demo() { println("LineElement's implementation invoked") } } // UniformElement inherits Element’s demo class UniformElement extends Element def invokeDemo(e: Element) { e.demo() } scala> invokeDemo(new ArrayElement) ArrayElement's implementation invoked scala> invokeDemo(new LineElement) LineElement's implementation invoked scala> invokeDemo(new UniformElement) Element's implementation invoked Dynamic Binding
  • 9. Subtyping • Polymorphism & dynamic binding Code Reuse • reuse instance variables and methods from super class Single Inheritance • cannot reuse code from more than one class Interfaces • support subtyping multiple classes • must re-implement interface Java-style Single Inheritance
  • 10. Trait • reusable unit of code • encapsulates method and field definitions • reused by mixing into classes • class can mix in any number of traits Applications • rich interfaces • stackable modifications
  • 11. trait Philosophical { def philosophize() { println("I consume memory, therefore I am!") } } class Frog extends Philosophical { override def toString = "green" } scala> val frog = new Frog frog: Frog = green scala> frog.philosophize() I consume memory, therefore I am! scala> val phil: Philosophical = frog phil: Philosophical = green scala> phil.philosophize() I consume memory, therefore I am! inheritance: code reuse subtyping: traits are types Defining and Using Traits
  • 12. class Animal trait HasLegs class Frog extends Animal with Philosophical with HasLegs { override def toString = "green" override def philosophize() { println("It ain't easy being " + toString + "!") } } superclass traits override code from trait scala> val phrog: Philosophical = new Frog phrog: Philosophical = green scala> phrog.philosophize() It ain't easy being green! Mixing in (multiple) traits
  • 13. Trait is like Java interface with • methods • fields • state Trait is Scala class • without class parameters • dynamic binding of ‘super’
  • 14. Rich interface • many methods • convenient for client • more work for implementer Thin interface • few methods • easy for implementers • inconvenient for client trait CharSequence { def charAt(index: Int): Char def length: Int def subSequence(start: Int, end: Int): CharSequence def toString(): String } Rich Interfaces with Traits • small number of abstract methods implemented by client • large number of concrete methods inherited by client
  • 15. class Point(val x: Int, val y: Int) class Rectangle(val topLeft: Point, val bottomRight: Point) { def left = topLeft.x def right = bottomRight.x def width = right - left // and many more geometric methods... } abstract class Component { def topLeft: Point def bottomRight: Point def left = topLeft.x def right = bottomRight.x def width = right - left // and many more geometric methods... } Rectangular objects without traits
  • 16. trait Rectangular { def topLeft: Point def bottomRight: Point def left = topLeft.x def right = bottomRight.x def width = right - left // and many more geometric methods... } abstract class Component extends Rectangular { // other methods... } class Rectangle(val topLeft: Point, val bottomRight: Point) extends Rectangular { // other methods... } Rectangular objects with traits
  • 17. trait Rectangular { def topLeft: Point def bottomRight: Point def left = topLeft.x def right = bottomRight.x def width = right - left // and many more geometric methods... } abstract class Component extends Rectangular { // other methods... } class Rectangle(val topLeft: Point, val bottomRight: Point) extends Rectangular { // other methods... } scala> val rect = new Rectangle(new Point(1, 1), new Point(10, 10)) rect: Rectangle = Rectangle@3536fd scala> rect.left res2: Int = 1 scala> rect.right res3: Int = 10 Rectangular objects with traits
  • 18. class Rational(n: Int, d: Int) { // ... def <(that: Rational) = this.numer * that.denom > that.numer * this.denom def >(that: Rational) = that < this def <=(that: Rational) = (this < that) || (this == that) def >=(that: Rational) = (this > that) || (this == that) } defined in terms of < based on standard semantics of ordering { A Rich Interface for Ordering
  • 19. class Rational(n: Int, d: Int) { // ... def <(that: Rational) = this.numer * that.denom > that.numer * this.denom def >(that: Rational) = that < this def <=(that: Rational) = (this < that) || (this == that) def >=(that: Rational) = (this > that) || (this == that) } defined in terms of < based on standard semantics of ordering { class Rational(n: Int, d: Int) extends Ordered[Rational] { // ... def compare(that: Rational) = (this.numer * that.denom) - (that.numer * this.denom) } A Rich Interface for Ordering
  • 20. class Rational(n: Int, d: Int) { // ... def <(that: Rational) = this.numer * that.denom > that.numer * this.denom def >(that: Rational) = that < this def <=(that: Rational) = (this < that) || (this == that) def >=(that: Rational) = (this > that) || (this == that) } defined in terms of < based on standard semantics of ordering { class Rational(n: Int, d: Int) extends Ordered[Rational] { // ... def compare(that: Rational) = (this.numer * that.denom) - (that.numer * this.denom) } Ordered trait provides reusable implementation of ordering A Rich Interface for Ordering
  • 21. Class Queue of integers • put: place integer in queue • get: take integer out • first-in first-out Modifications • Doubling: double all integers put in queue • Incrementing: increment all integers put in queue • Filtering: filter out negative Stackable Modifications
  • 22. abstract class IntQueue { def get(): Int def put(x: Int) } import scala.collection.mutable.ArrayBuffer class BasicIntQueue extends IntQueue { private val buf = new ArrayBuffer[Int] def get() = buf.remove(0) def put(x: Int) { buf += x } } Class Queue
  • 23. abstract class IntQueue { def get(): Int def put(x: Int) } import scala.collection.mutable.ArrayBuffer class BasicIntQueue extends IntQueue { private val buf = new ArrayBuffer[Int] def get() = buf.remove(0) def put(x: Int) { buf += x } } scala> val queue = new BasicIntQueue queue: BasicIntQueue = BasicIntQueue@24655f scala> queue.put(10) scala> queue.put(20) scala> queue.get() res9: Int = 10 scala> queue.get() res10: Int = 20 Class Queue
  • 24. trait Doubling extends IntQueue { abstract override def put(x: Int) { super.put(2 * x) } } dynamically bound can only be mixed into subclasses of IntQueue mix into class with concrete definition Trait Doubling
  • 25. trait Doubling extends IntQueue { abstract override def put(x: Int) { super.put(2 * x) } } dynamically bound can only be mixed into subclasses of IntQueue mix into class with concrete definition scala> class MyQueue extends BasicIntQueue with Doubling defined class MyQueue scala> val queue = new MyQueue queue: MyQueue = MyQueue@91f017 scala> queue.put(10) scala> queue.get() res12: Int = 20 Trait Doubling
  • 26. trait Doubling extends IntQueue { abstract override def put(x: Int) { super.put(2 * x) } } dynamically bound can only be mixed into subclasses of IntQueue mix into class with concrete definition scala> class MyQueue extends BasicIntQueue with Doubling defined class MyQueue scala> val queue = new MyQueue queue: MyQueue = MyQueue@91f017 scala> queue.put(10) scala> queue.get() res12: Int = 20 scala> val queue = new BasicIntQueue with Doubling queue: BasicIntQueue with Doubling = $anon$1@5fa12d scala> queue.put(10) scala> queue.get() res14: Int = 20 Trait Doubling
  • 27. trait Incrementing extends IntQueue { abstract override def put(x: Int) { super.put(x + 1) } } trait Filtering extends IntQueue { abstract override def put(x: Int) { if (x >= 0) super.put(x) } } Stacking Modifications
  • 28. trait Incrementing extends IntQueue { abstract override def put(x: Int) { super.put(x + 1) } } trait Filtering extends IntQueue { abstract override def put(x: Int) { if (x >= 0) super.put(x) } } scala> val queue = (new BasicIntQueue with Incrementing with Filtering) scala> queue.put(-1); queue.put(0); queue.put(1) scala> queue.get() res15: Int = 1 scala> queue.get() res15: Int = 2 Stacking Modifications
  • 29. trait Incrementing extends IntQueue { abstract override def put(x: Int) { super.put(x + 1) } } trait Filtering extends IntQueue { abstract override def put(x: Int) { if (x >= 0) super.put(x) } } scala> val queue = (new BasicIntQueue with Incrementing with Filtering) scala> queue.put(-1); queue.put(0); queue.put(1) scala> queue.get() res15: Int = 1 scala> queue.get() res15: Int = 2 Stacking Modifications scala> val queue = (new BasicIntQueue with Filtering with Incrementing) scala> queue.put(-1); queue.put(0); queue.put(1) scala> queue.get() res17: Int = 0 scala> queue.get() res18: Int = 1 scala> queue.get() res19: Int = 2
  • 30. // Multiple inheritance thought experiment val q = new BasicIntQueue with Incrementing with Doubling q.put(42) // which put would be called? Multiple Inheritance (Why Not?) Incrementing Doubling BasicIntQueue new BasicIntQueue with Increment with Doubling
  • 31. // Multiple inheritance thought experiment trait MyQueue extends BasicIntQueue with Incrementing with Doubling { def put(x: Int) { Incrementing.super.put(x) // (Not real Scala) Doubling.super.put(x) } } Multiple Inheritance (Why Not?) Incrementing Doubling BasicIntQueue new BasicIntQueue with Increment with Doubling put of BasicIntQue called twice!
  • 32. a class is always linearized before all of its superclasses and mixed in traits class Animal trait Furry extends Animal trait HasLegs extends Animal trait FourLegged extends HasLegs class Cat extends Animal with Furry with FourLegged Linearly Ordering Traits
  • 33. Units of code • reusable through inheritance • can be mixed in at multiple places in hierarchy Multiple inheritance ++ • calls to super are linearized • avoid diamond problem • stack changes Traits Summary
  • 34. What is the value of question in: class Animal { override def toString = "Animal" } trait Furry extends Animal { override def toString = "Furry -> " + super.toString } trait HasLegs extends Animal { override def toString = "HasLegs -> " + super.toString } trait FourLegged extends HasLegs { override def toString = "FourLegged -> " + super.toString } class Cat extends Animal with Furry with FourLegged { override def toString = "Cat -> " + super.toString } val question = new Cat a) Cat -> FourLegged -> HasLegs -> Furry -> Animal b) Cat -> HasLegs -> FourLegged -> Furry -> Animal c) Cat -> Furry -> FourLegged -> HasLegs -> Animal d) Cat -> Furry -> HasLegs -> FourLegged -> Animal Traits Experiment
  • 36. def append[T](xs: List[T], ys: List[T]): List[T] = xs match { case List() => ys case x :: xs1 => x :: append(xs1, ys) }
  • 37. def map[A,B](xs: List[A], f: A => B): List[B] = xs match { case List() => List() case y :: ys => f(y) :: map(ys, f) }
  • 38. Generic classes and traits • Set[T]: generic sets parameterized with type T • Set[Int]: set of integers, instance of Set[T] • No raw types: always use with type parameter Example: Functional Queues
  • 39. typedef struct queue_elem { int val; struct queue_elem *next; } queue_elem; typedef struct queue { queue_elem *first; queue_elem *last; } queue; queue *newQueue() { queue *q = (queue *)malloc(sizeof(queue)); q->first = NULL; q->last = NULL; return q; } Imperative Queue in C
  • 40. void enqueue(queue *q, int val) { queue_elem *elem = (queue_elem *)malloc(sizeof(queue_elem)); elem->val = val; elem->next = NULL; if(q->first == NULL) { q->first = q->last = elem; } else { q->last->next = elem; q->last = elem; } } Imperative Queue in C
  • 41. int dequeue(queue *q) { if(q == NULL || q->first == NULL) { return 0; } int val = q->first->val; queue_elem *elem = q->first; if(q->first == q->last) { q->last = NULL; } q->first = q->first->next; free(elem); return val; } Imperative Queue in C
  • 42. Queue operations • head: return first element • tail: return rest • append: new queue with new element at the end Functional Queue • fully persistent • contents not changed when appending • efficient implementation should be O(1) for all operations scala> val q = Queue(1, 2, 3) q: Queue[Int] = Queue(1, 2, 3) scala> val q1 = q append 4 q1: Queue[Int] = Queue(1, 2, 3, 4) scala> q res0: Queue[Int] = Queue(1, 2, 3) Functional Queue
  • 43. class SlowAppendQueue[T](elems: List[T]) { // Not efficient def head = elems.head def tail = new SlowAppendQueue(elems.tail) def append(x: T) = new SlowAppendQueue(elems ::: List(x)) } Functional Queue (First Attempt)
  • 44. class SlowAppendQueue[T](elems: List[T]) { // Not efficient def head = elems.head def tail = new SlowAppendQueue(elems.tail) def append(x: T) = new SlowAppendQueue(elems ::: List(x)) } append = O(n) Functional Queue (First Attempt)
  • 45. class SlowAppendQueue[T](elems: List[T]) { // Not efficient def head = elems.head def tail = new SlowAppendQueue(elems.tail) def append(x: T) = new SlowAppendQueue(elems ::: List(x)) } class SlowHeadQueue[T](smele: List[T]) { // Not efficient // smele is elems reversed def head = smele.last def tail = new SlowHeadQueue(smele.init) def append(x: T) = new SlowHeadQueue(x :: smele) } append = O(n) Functional Queue (First Attempt)
  • 46. class SlowAppendQueue[T](elems: List[T]) { // Not efficient def head = elems.head def tail = new SlowAppendQueue(elems.tail) def append(x: T) = new SlowAppendQueue(elems ::: List(x)) } class SlowHeadQueue[T](smele: List[T]) { // Not efficient // smele is elems reversed def head = smele.last def tail = new SlowHeadQueue(smele.init) def append(x: T) = new SlowHeadQueue(x :: smele) } append = O(n) head, tail = O(n) Functional Queue (First Attempt)
  • 47. class SlowAppendQueue[T](elems: List[T]) { // Not efficient def head = elems.head def tail = new SlowAppendQueue(elems.tail) def append(x: T) = new SlowAppendQueue(elems ::: List(x)) } class SlowHeadQueue[T](smele: List[T]) { // Not efficient // smele is elems reversed def head = smele.last def tail = new SlowHeadQueue(smele.init) def append(x: T) = new SlowHeadQueue(x :: smele) } append = O(n) head, tail = O(n) head, tail, append = O(1) cannot be possible! Functional Queue (First Attempt)
  • 48. class Queue[T]( private val leading: List[T], private val trailing: List[T] ) { def head = leading.head def tail = new Queue(leading.tail, trailing) def append(x: T) = new Queue(leading, x :: trailing) } elems == leading ::: trailing.reverse Represent Queue with Two Lists
  • 49. class Queue[T]( private val leading: List[T], private val trailing: List[T] ) { def head = leading.head def tail = new Queue(leading.tail, trailing) def append(x: T) = new Queue(leading, x :: trailing) } elems == leading ::: trailing.reverse but what if leading.isEmpty? Represent Queue with Two Lists
  • 50. Mirroring class Queue[T]( private val leading: List[T], private val trailing: List[T] ) { private def mirror = if (leading.isEmpty) new Queue(trailing.reverse, Nil) else this def head = mirror.leading.head def tail = { val q = mirror new Queue(q.leading.tail, q.trailing) } def append(x: T) = new Queue(leading, x :: trailing) }
  • 51. Mirroring class Queue[T]( private val leading: List[T], private val trailing: List[T] ) { private def mirror = if (leading.isEmpty) new Queue(trailing.reverse, Nil) else this def head = mirror.leading.head def tail = { val q = mirror new Queue(q.leading.tail, q.trailing) } def append(x: T) = new Queue(leading, x :: trailing) } head, tail, append: O(1) mirror: O(n) but amortized over n calls of tail
  • 52. Mirroring class Queue[T]( private val leading: List[T], private val trailing: List[T] ) { private def mirror = if (leading.isEmpty) new Queue(trailing.reverse, Nil) else this def head = mirror.leading.head def tail = { val q = mirror new Queue(q.leading.tail, q.trailing) } def append(x: T) = new Queue(leading, x :: trailing) } head, tail, append: O(1) mirror: O(n) but amortized over n calls of tail implementation is exposed!
  • 53. class Queue[T] private ( private val leading: List[T], private val trailing: List[T] ) { def this() = this(Nil, Nil) def this(elems: T*) = this(elems.toList, Nil) def head = ... def tail = ... def append(x: T) = ... } scala> Queue(1, 2, 3) private parameters public auxiliary constructors hide implementation details from clients Private Constructors
  • 54. class Queue[T] private ( private val leading: List[T], private val trailing: List[T] ) { def head = ... def tail = ... def append(x: T) = ... } object Queue { // constructs a queue with initial elements ‘xs’ def apply[T](xs: T*) = new Queue[T](xs.toList, Nil) } Factory Method hide implementation details from clients factory method private parameters
  • 55. trait Queue[T] { def head: T def tail: Queue[T] def append(x: T): Queue[T] } object Queue { def apply[T](xs: T*): Queue[T] = new QueueImpl[T](xs.toList, Nil) private class QueueImpl[T]( private val leading: List[T], private val trailing: List[T] ) extends Queue[T] { def mirror = if (leading.isEmpty) new QueueImpl(trailing.reverse, Nil) else this def head: T = mirror.leading.head def tail: QueueImpl[T] = { val q = mirror new QueueImpl(q.leading.tail, q.trailing) } def append(x: T) = new QueueImpl(leading, x :: trailing) } } hide implementation details from clients
  • 56. scala> def doesNotCompile(q: Queue) {} <console>:5: error: trait Queue takes type parameters def doesNotCompile(q: Queue) {} scala> def doesCompile(q: Queue[AnyRef]) {} doesCompile: (Queue[AnyRef])Unit Queue is a trait, not a type Queue is a type constructor or generic trait Queue[String] is a (specific) type Generic Traits
  • 57. Queue[String] subtype of Queue[AnyRef] ? if S subtype of T then Queue[S] subtype of Queue[T] ? If answer is yes: Queue is covariant in T trait Queue[+T] { ... } val q: Queue[AnyRef] = Queue[String](“a”) If answer is no: Queue is contravariant in T trait Queue[-T] { ... } val q: Queue[String] = Queue[AnyRef]()default: nonvariant Subtyping &Variance Annotations
  • 58. class Cell[+T](init: T) { private[this] var current = init def get = current def set(x: T) { current = x } } val c1 = new Cell[String]("abc") val c2: Cell[Any] = c1 c2.set(1) val s: String = c1.get Covariance and Mutable Classes
  • 59. class Cell[+T](init: T) { private[this] var current = init def get = current def set(x: T) { current = x } } val c1 = new Cell[String]("abc") val c2: Cell[Any] = c1 c2.set(1) val s: String = c1.get Cell.scala:7: error: covariant type T occurs in contravariant position in type T of value x def set(x: T) = current = x Covariance and Mutable Classes
  • 60. package society { package professional { class Executive { private[professional] var workDetails = null private[society] var friends = null private[this] var secrets = null def help(another : Executive) { println(another.workDetails) println(another.secrets) //ERROR } } } } Source: http://www.tutorialspoint.com/scala/scala_access_modifiers.htm Scope of Protection of Access Modifiers A private member is visible only inside the class or object that contains the member definition. A protected member is only accessible from subclasses of the class in which the member is defined. Every member not labeled private or protected is public. There is no explicit modifier for public members. Such members can be accessed from anywhere.
  • 61. // this is Java String[] a1 = { "abc" }; Object[] a2 = a1; a2[0] = new Integer(17); String s = a1[0]; no compile-time error Variance and Arrays
  • 62. // this is Java String[] a1 = { "abc" }; Object[] a2 = a1; a2[0] = new Integer(17); String s = a1[0]; Exception in thread "main" java.lang.ArrayStoreException: java.lang.Integer at JavaArrays.main(JavaArrays.java:8) no compile-time error Variance and Arrays
  • 63. // this is Java String[] a1 = { "abc" }; Object[] a2 = a1; a2[0] = new Integer(17); String s = a1[0]; Exception in thread "main" java.lang.ArrayStoreException: java.lang.Integer at JavaArrays.main(JavaArrays.java:8) no compile-time error motivation: generic treatment of arrays: void sort(Object[] a, Comparator cmp) { ... } Variance and Arrays
  • 64. scala> val a1 = Array("abc") a1: Array[java.lang.String] = Array(abc) scala> val a2: Array[Any] = a1 <console>:5: error: type mismatch; found : Array[java.lang.String] required: Array[Any] val a2: Array[Any] = a1 ˆ scala> val a2: Array[Object] = a1.asInstanceOf[Array[Object]] a2: Array[java.lang.Object] = Array(abc) Scala Arrays are Non-variant
  • 65. class Queue[+T] { def append(x: T) = ... } class StrangeIntQueue extends Queue[Int] { override def append(x: Int) = { println(Math.sqrt(x)) super.append(x) } } val x: Queue[Any] = new StrangeIntQueue x.append("abc") CheckingVariance Annotations
  • 66. class Queue[+T] { def append(x: T) = ... } class StrangeIntQueue extends Queue[Int] { override def append(x: Int) = { println(Math.sqrt(x)) super.append(x) } } val x: Queue[Any] = new StrangeIntQueue x.append("abc") Queues.scala:11: error: covariant type T occurs in contravariant position in type T of value x def append(x: T) = ˆ CheckingVariance Annotations
  • 67. class Queue[+T]( private val leading: List[T], private val trailing: List[T] ) { def append[U >: T](x: U) = new Queue[U](leading, x :: trailing) // ... } class Fruit class Apple extends Fruit class Orange extends Fruit scala> val qa = Queue(new Apple) scala> val qb = qa.append(new Orange) qb: Queue[Fruit] = ... U >: T == U is a supertype of T Lower Bounds
  • 68. class Queue[+T] private ( private[this] var leading: List[T], private[this] var trailing: List[T] ) { private def mirror() = if (leading.isEmpty) { while (!trailing.isEmpty) { leading = trailing.head :: leading trailing = trailing.tail } } def head: T = { mirror(); leading.head } def tail: Queue[T] = { mirror(); new Queue(leading.tail, trailing) } def append[U >: T](x: U) = new Queue[U](leading, x :: trailing) } Optimized Functional Queue
  • 69. def orderedMergeSort[T <: Ordered[T]](xs: List[T]): List[T] = { def merge(xs: List[T], ys: List[T]): List[T] = (xs, ys) match { case (Nil, _) => ys case (_, Nil) => xs case (x :: xs1, y :: ys1) => if (x < y) x :: merge(xs1, ys) else y :: merge(xs, ys1) } val n = xs.length / 2 if (n == 0) xs else { val (ys, zs) = xs splitAt n merge(orderedMergeSort(ys), orderedMergeSort(zs)) } } Upperbounds
  • 70. Information hiding • private constructors • factory methods • object private members Type variance • subtyping of generic types • covariant, contravariant variance annotations • lower bounds, upper bounds Type Parameterization Summary
  • 71. Reading & Programming in Week 6 Reading Scala Chapter 12: Traits Scala Chapter 19: Type Parameterization Week 9: Parsers and Interpreters WebLab: Graded Assignment 2: (deadline 14 May 2013, 23:59)