104
Settembre 2015 @filippovitale Polimorfismo parametrico, polimorfismo su misura e polimorfismo cosa?

Polimorfismo cosa?

Embed Size (px)

Citation preview

Page 1: Polimorfismo cosa?

Settembre 2015

@filippovitale

Polimorfismo parametrico, polimorfismo su misura e

polimorfismo cosa?

Page 2: Polimorfismo cosa?
Page 3: Polimorfismo cosa?
Page 4: Polimorfismo cosa?

3 sempliciData Structure

Page 5: Polimorfismo cosa?

Seq Set Map

package scala.collection

Page 6: Polimorfismo cosa?

Seq Set Map

package scala.collection

v v v v

Page 7: Polimorfismo cosa?

Seq Set Map

package scala.collection

valueAvalueB

valueC

Page 8: Polimorfismo cosa?

Seq Set Map

package scala.collection

key value

key value

key value

Page 9: Polimorfismo cosa?

Seq Set Map

package scala.collection

base trait per implementazioni mutable e immutable

Page 10: Polimorfismo cosa?

package scala.collection

Seq Set Map

package scala.collection.mutable

ArrayBuffer HashSet HashMap

Page 11: Polimorfismo cosa?

package scala.collection.mutable

ArrayBuffer HashSet HashMap

“Mutability is an optimisation – perhaps premature”

Page 12: Polimorfismo cosa?

package scala.collection

Seq Set

package scala.collection.immutable

Map

List HashSet HashMap

package scala.collection.mutable

ArrayBuffer HashSet HashMap

http://docs.scala-lang.org/tutorials/FAQ/collections.html

Page 13: Polimorfismo cosa?

package scala.collection.immutable

List HashSet HashMap

Immutabilità implica:- equational reasoning- sharing with referential integrity- thread safety- …

Page 14: Polimorfismo cosa?

“When you get used to immutable data, ya kinda forget how to use mutable data in a sensible way.” – Jessica Kerr

Page 15: Polimorfismo cosa?

package scala.collection

Traversable

Seq Set Map

Page 16: Polimorfismo cosa?

Quali metodi offreTraversable?

Page 17: Polimorfismo cosa?

Metodi offerti da TraversableisEmptysizehasDefiniteSize++mapflatMapfilterremovepartitiongroupByforeach

reduceRightOptheadheadOptiontaillastlastOptioninittakedropslicetakeWhile

forallexistscountfindfoldLeft/:foldRight:\reduceLeftreduceLeftOptreduceRight

dropWhilespansplitAttoArraytoListtoIterabletoSeqtoStreamsortWithmkStringtoString

Page 18: Polimorfismo cosa?

isEmptysizehasDefiniteSize++mapflatMapfilterremovepartitiongroupByforeach

reduceRightOptheadheadOptiontaillastlastOptioninittakedropslicetakeWhile

forallexistscountfindfoldLeft/:foldRight:\reduceLeftreduceLeftOptreduceRight

dropWhilespansplitAttoArraytoListtoIterabletoSeqtoStreamsortWithmkStringtoString

Metodi offerti da Traversabledef map[B](f: A => B)

Page 19: Polimorfismo cosa?

isEmptysizehasDefiniteSize++mapflatMapfilterremovepartitiongroupByforeach

reduceRightOptheadheadOptiontaillastlastOptioninittakedropslicetakeWhile

forallexistscountfindfoldLeft/:foldRight:\reduceLeftreduceLeftOptreduceRight

dropWhilespansplitAttoArraytoListtoIterabletoSeqtoStreamsortWithmkStringtoString

Metodi offerti da Traversable

def foreach(f: (A) => Unit): Unit

def map[B](f: A => B)

Page 20: Polimorfismo cosa?

Metodi offerti da TraversableisEmptysizehasDefiniteSize++mapflatMapfilterremovepartitiongroupByforeach

reduceRightOptheadheadOptiontaillastlastOptioninittakedropslicetakeWhile

forallexistscountfindfoldLeft/:foldRight:\reduceLeftreduceLeftOptreduceRight

dropWhilespansplitAttoArraytoListtoIterabletoSeqtoStreamsortWithmkStringtoString

Page 21: Polimorfismo cosa?

isEmptysizehasDefiniteSize++mapflatMapfilterremovepartitiongroupByforeach

reduceRightOptheadheadOptiontaillastlastOptioninittakedropslicetakeWhile

forallexistscountfindfoldLeft/:foldRight:\reduceLeftreduceLeftOptreduceRight

dropWhilespansplitAttoArraytoListtoIterabletoSeqtoStreamsortWithmkStringtoString

Metodi offerti da Traversabledef foldLeft[B](z: B)(f: (B, A) => B): B

Page 22: Polimorfismo cosa?

isEmptysizehasDefiniteSize++mapflatMapfilterremovepartitiongroupByforeach

reduceRightOptheadheadOptiontaillastlastOptioninittakedropslicetakeWhile

forallexistscountfindfoldLeft/:foldRight:\reduceLeftreduceLeftOptreduceRight

dropWhilespansplitAttoArraytoListtoIterabletoSeqtoStreamsortWithmkStringtoString

Metodi offerti da Traversabledef foldLeft[B](z: B)(f: (B, A) => B): B

def /:[B](z: B)(op: (B, A) => B): B = foldLeft(z)(op)

Page 23: Polimorfismo cosa?

isEmptysizehasDefiniteSize++mapflatMapfilterremovepartitiongroupByforeach

reduceRightOptheadheadOptiontaillastlastOptioninittakedropslicetakeWhile

forallexistscountfindfoldLeft/:foldRight:\reduceLeftreduceLeftOptreduceRight

dropWhilespansplitAttoArraytoListtoIterabletoSeqtoStreamsortWithmkStringtoString

Metodi offerti da Traversabledef foldLeft[B](z: B)(f: (B, A) => B): B

def /:[B](z: B)(op: (B, A) => B): B = foldLeft(z)(op)

Page 24: Polimorfismo cosa?

Theorems for free! – http://ttic.uchicago.edu/~dreyer/course/papers/wadler.pdf

Page 25: Polimorfismo cosa?

Parametricity – http://yowconference.com.au/slides/yowlambdajam2014/Morris-ParametricityTypesAreDocumentation.pdf

Page 26: Polimorfismo cosa?

Unire Strutture Dati

Page 27: Polimorfismo cosa?

Metodi offerti da TraversableisEmptysizehasDefiniteSize++mapflatMapfilterremovepartitiongroupByforeach

reduceRightOptheadheadOptiontaillastlastOptioninittakedropslicetakeWhile

forallexistscountfindfoldLeft/:foldRight:\reduceLeftreduceLeftOptreduceRight

dropWhilespansplitAttoArraytoListtoIterabletoSeqtoStreamsortWithmkStringtoString

Page 28: Polimorfismo cosa?

Metodi offerti da TraversableisEmptysizehasDefiniteSize++mapflatMapfilterremovepartitiongroupByforeach

reduceRightOptheadheadOptiontaillastlastOptioninittakedropslicetakeWhile

forallexistscountfindfoldLeft/:foldRight:\reduceLeftreduceLeftOptreduceRight

dropWhilespansplitAttoArraytoListtoIterabletoSeqtoStreamsortWithmkStringtoString

def ++[B](that: Traversable[B]): Traversable[B]

Page 29: Polimorfismo cosa?

Metodi offerti da TraversableisEmptysizehasDefiniteSize++mapflatMapfilterremovepartitiongroupByforeach

reduceRightOptheadheadOptiontaillastlastOptioninittakedropslicetakeWhile

forallexistscountfindfoldLeft/:foldRight:\reduceLeftreduceLeftOptreduceRight

dropWhilespansplitAttoArraytoListtoIterabletoSeqtoStreamsortWithmkStringtoString

def ++[B](that: Traversable[B]): Traversable[B]

Traversable Seq List

Page 30: Polimorfismo cosa?

List(1, 2, 3) ++ List(4, 5, 6) == ???

Page 31: Polimorfismo cosa?

List(1, 2, 3) ++ List(4, 5, 6) == List(1, 2, 3, 4, 5, 6)

Page 32: Polimorfismo cosa?

Metodi offerti da TraversableisEmptysizehasDefiniteSize++mapflatMapfilterremovepartitiongroupByforeach

reduceRightOptheadheadOptiontaillastlastOptioninittakedropslicetakeWhile

forallexistscountfindfoldLeft/:foldRight:\reduceLeftreduceLeftOptreduceRight

dropWhilespansplitAttoArraytoListtoIterabletoSeqtoStreamsortWithmkStringtoString

def ++[B](that: Traversable[B]): Traversable[B]

Traversable Set HashSet

Page 33: Polimorfismo cosa?

Set(1, 2, 3) ++ Set(4, 5, 6) == ???

Page 34: Polimorfismo cosa?

Set(1, 2, 3) ++ Set(4, 5, 6) == Set(5, 1, 6, 2, 3, 4)

Page 35: Polimorfismo cosa?

Set(1, 2, 3) ++ Set(4, 5, 6) == Set(5, 1, 6, 2, 3, 4)

Set(1, 2) ++ Set(2, 3) == Set(1, 2, 3)

Page 36: Polimorfismo cosa?

Metodi offerti da TraversableisEmptysizehasDefiniteSize++mapflatMapfilterremovepartitiongroupByforeach

reduceRightOptheadheadOptiontaillastlastOptioninittakedropslicetakeWhile

forallexistscountfindfoldLeft/:foldRight:\reduceLeftreduceLeftOptreduceRight

dropWhilespansplitAttoArraytoListtoIterabletoSeqtoStreamsortWithmkStringtoString

def ++[B](that: Traversable[B]): Traversable[B]

Traversable Map HashMap

Page 37: Polimorfismo cosa?

Map("a" -> 1) ++ Map("b" -> 2) == Map("a" -> 1, "b" -> 2)

Page 38: Polimorfismo cosa?

E in casi più complessi?

Page 39: Polimorfismo cosa?

Map[String, Set[Int]]

Page 40: Polimorfismo cosa?

Map[String, Set[Int]]

“a” Set(1, 2)

“key b” Set(4, 7, 5)

“key c” Set(9, 4)

“a” Set(2, 3)

“key c” Set(3, 4)

“key d” Set(5, 6)

Page 41: Polimorfismo cosa?

Map("a" -> Set(1, 2)) ++ Map("a" -> Set(2, 3)) == ???

Page 42: Polimorfismo cosa?

Map("a" -> Set(1, 2)) ++ Map("a" -> Set(2, 3)) == ???

1: Map("a" -> Set(1, 2))

2: Map("a" -> Set(1, 2, 3))

3: Map("a" -> Set(2, 3))

4: RuntimeException

5: Compiler Error

Page 43: Polimorfismo cosa?

Map("a" -> Set(1, 2)) ++ Map("a" -> Set(2, 3)) == ???

1:

2:

3: Map("a" -> Set(2, 3))

4:

5:

Page 44: Polimorfismo cosa?

Map("a" -> Set(1, 2)) ??? Map("a" -> Set(2, 3))

Map("a" -> Set(1, 2, 3))

Page 45: Polimorfismo cosa?

Metodi offerti da TraversableisEmptysizehasDefiniteSize++mapflatMapfilterremovepartitiongroupByforeach

reduceRightOptheadheadOptiontaillastlastOptioninittakedropslicetakeWhile

forallexistscountfindfoldLeft/:foldRight:\reduceLeftreduceLeftOptreduceRight

dropWhilespansplitAttoArraytoListtoIterabletoSeqtoStreamsortWithmkStringtoString

Seq Set Map✔ ✔ ✘

Page 46: Polimorfismo cosa?

Quando vuoi un lavoro fatto bene…

Page 47: Polimorfismo cosa?

“a” Set(1, 2) “a” Set(2, 3)

“a” Set(1, 2) ++ Set(2, 3)

Page 48: Polimorfismo cosa?

“a” Set(1, 2) “a” Set(2, 3)

“a” Set(1, 2, 3)

Page 49: Polimorfismo cosa?

def blend(ma: Map[String, Set[Int]], mb: Map[String, Set[Int]]): Map[String, Set[Int]]

Page 50: Polimorfismo cosa?

def blend(ma: Map[String, Set[Int]], mb: Map[String, Set[Int]]): Map[String, Set[Int]] = { mb foreach { case (k, v) => ??? } }

Page 51: Polimorfismo cosa?

def blend(ma: Map[String, Set[Int]], mb: Map[String, Set[Int]]): Map[String, Set[Int]] = { val result = mutable.Map() ++ ma mb foreach { case (k, v) => ??? } result.toMap}

Page 52: Polimorfismo cosa?

def blend(ma: Map[String, Set[Int]], mb: Map[String, Set[Int]]): Map[String, Set[Int]] = { val result = mutable.Map() ++ ma mb foreach { case (k, v) => if (result.contains(k)) result += k -> (result(k) ++ v) else result += k -> v } result.toMap}

Page 53: Polimorfismo cosa?

Implementazionecon Map immutable

Page 54: Polimorfismo cosa?

def blend(ma: Map[String, Set[Int]], mb: Map[String, Set[Int]]): Map[String, Set[Int]] = {

}

(ma /: mb) { case (result,(k, v)) => if (result.contains(k)) result + (k -> (result(k) ++ v)) else result + (k -> v)}

val result = mutable.Map() ++ mamb foreach { case (k, v) => if (result.contains(k)) result += k -> (result(k) ++ v) else result += k -> v}result.toMap

Page 55: Polimorfismo cosa?

def blend(ma: Map[String, Set[Int]], mb: Map[String, Set[Int]]): Map[String, Set[Int]] = { (ma /: mb) { case (result,(k, v)) => if (result.contains(k)) result + (k -> (result(k) ++ v)) else result + (k -> v) }}

Page 56: Polimorfismo cosa?

(ma /: mb) { case (result,(k, v)) =>result + (k -> { result.get(k) match { case Some(vr) => vr ++ v case None => v }}

Page 57: Polimorfismo cosa?

(ma /: mb) { case (result,(k, v)) =>result + (k -> { result.get(k) match { case Some(vr) => vr ++ v case None => v } // .map(_ ++ v).getOrElse(v)

}}

Page 58: Polimorfismo cosa?

(ma /: mb) { case (result,(k, v)) =>result + (k -> { result.get(k) match { case Some(vr) => vr ++ v case None => v } // .map(_ ++ v).getOrElse(v) // .some(_ ++ v).none(v)

}}

Page 59: Polimorfismo cosa?

(ma /: mb) { case (result,(k, v)) =>result + (k -> { result.get(k) match { case Some(vr) => vr ++ v case None => v } // .map(_ ++ v).getOrElse(v) // .some(_ ++ v).none(v) // .fold(v)(_ ++ v)

}}

Page 60: Polimorfismo cosa?

(ma /: mb) { case (result,(k, v)) =>result + (k -> { result.get(k) match { case Some(vr) => vr ++ v case None => v } // .map(_ ++ v).getOrElse(v) // .some(_ ++ v).none(v) // .fold(v)(_ ++ v) // .cata(_ ++ v, v)}}

“FP with Bananas, Lenses, Envelopes and Barbed Wire” – http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125http://en.wikipedia.org/wiki/Catamorphism

Page 61: Polimorfismo cosa?

(ma /: mb) { case (result,(k, v)) =>result + (k -> { result.get(k) match { case Some(vr) => vr ++ v case None => v } // .map(_ ++ v).getOrElse(v) // .some(_ ++ v).none(v) // .fold(v)(_ ++ v) // .cata(_ ++ v, v)}}

http://stackoverflow.com/questions/5328007/why-doesnt-option-have-a-fold-method

Page 62: Polimorfismo cosa?

(ma /: mb) { case (result,(k, v)) =>result + (k -> { result.get(k) match { case Some(vr) => vr ++ v case None => v } // .map(_ ++ v).getOrElse(v) // .some(_ ++ v).none(v) // .fold(v)(_ ++ v) // .cata(_ ++ v, v)}}

http://stackoverflow.com/questions/5328007/why-doesnt-option-have-a-fold-method

Page 63: Polimorfismo cosa?

(ma /: mb) { case (result, (k, v)) => result + (k -> result.get(k).cata(_ ++ v, v))}

mb foreach { case (k, v) => result += (k -> result.get(k).cata(_ ++ v, v))}

Page 64: Polimorfismo cosa?

(ma /: mb) { case (result, (k, v)) => result + (k -> result.get(k).cata(_ ++ v, v))}

mb foreach { case (k, v) => result += (k -> result.get(k).cata(_ ++ v, v))}

Page 65: Polimorfismo cosa?
Page 66: Polimorfismo cosa?

E se volessimo unire due mappe con type diversi?

Page 67: Polimorfismo cosa?

Map[String, Set[Int]] Map[String, Map[Int, Set[Int]]]

Page 68: Polimorfismo cosa?

Map[String, Set[Int]] Map[String, Map[Int, Set[Int]]]

def blend(ma: Map[String, Set[Int]], mb: Map[String, Set[Int]]): Map[String, Set[Int]] = ???

def blend(ma: Map[String, Map[Int, Set[Int]]], mb: Map[String, Map[Int, Set[Int]]]): Map[String, Map[Int, Set[Int]]] = ???

Page 69: Polimorfismo cosa?

Map[String, Set[Int]] Map[String, Map[Int, Set[Int]]]

(ma /: mb) { case (result, (k, v)) => result + (k -> result.get(k).cata(_ ++ v, v)) }

(ma /: mb) { case (result, (k, v)) => result + ??? // { ??? => { ??? } } }

Page 70: Polimorfismo cosa?

Map[String, Set[Int]] Map[String, Map[Int, Set[Int]]]

trait Blendable[A] { def blend(ma: A, mb: A): A}

Page 71: Polimorfismo cosa?

Map[String, Set[Int]] Map[String, Map[Int, Set[Int]]]

trait Blendable[A] { def blend(ma: A, mb: A): A}

new Blendable[...] { def blend(ma: ..., mb: ...): ... = ???}

Page 72: Polimorfismo cosa?

Map[String, Set[Int]] Map[String, Map[Int, Set[Int]]]

trait Blendable[A] { def blend(ma: A, mb: A): A}

new Blendable[...] { def blend(ma: ..., mb: ...): ... = ???}x10 Developer

Page 73: Polimorfismo cosa?

Cosa intendiamo veramente per “blend”

Page 74: Polimorfismo cosa?

List utilizzando l’operatore binario ++

Set utilizzando l’operatore binario ++

List(1, 2, 3) ++ List(4, 5, 6) == List(1, 2, 3, 4, 5, 6)

Set(1, 2) ++ Set(2, 3) == Set(1, 2, 3)

Page 75: Polimorfismo cosa?

(List, ++)(Set, ++)

(1 blend 2) == ???

Page 76: Polimorfismo cosa?

(List, ++)(Set, ++)

(Int, +)

(1 blend 2) == 1 + 2 == 3

Page 77: Polimorfismo cosa?

(List, ++)(Set, ++)

(Int, +)(String, +)("ab" blend "cd") == ("ab" + "cd") == "abcd"

Page 78: Polimorfismo cosa?

(List, ++)(Set, ++)

(Int, +)(String, +)

(Map[...], Blendable[...].blend)

Blendable[Map[String, Set[Int]]].blend(ma, mb)

Page 79: Polimorfismo cosa?

Cosa potrebbe consigliarci un Matematico?

Page 80: Polimorfismo cosa?

WARNING

Algebra ahead

Page 81: Polimorfismo cosa?

https://it.wikipedia.org/wiki/Semigruppo

“Un semigruppo è un insieme S munito di una operazione binaria associativa m: S × S → S”

Page 82: Polimorfismo cosa?

https://it.wikipedia.org/wiki/Propriet%C3%A0_di_chiusura

Proprietà di chiusura ≝ ∀a, b ∈ T : a∙b ∈ T

Per ogni a, b in T, il risultato dell’operazione a⋅b è in T:

trait Semigroup[T] { def op(a: T, b: T): T}

def op(a: Boolean, b: Boolean): Boolean

def op(a: Int, b: Int): Boolean

Page 83: Polimorfismo cosa?

https://it.wikipedia.org/wiki/Associativit%C3%A0

Legge Associativa ≝ ∀a, b, c ∈ T : (a∙b)∙c = a∙(b∙c)

Ogni a, b e c in T soddisfano (a∙b)∙c = a∙(b∙c)

trait Semigroup[T] { def op(a: T, b: T): T}

((a op b) op c) == (a op (b op c))

Page 84: Polimorfismo cosa?

https://it.wikipedia.org/wiki/Semigruppo

“Un semigruppo è un insieme S munito di una operazione binaria associativa m: S × S → S”

Page 85: Polimorfismo cosa?

Scalaz e Semigruppi

Page 86: Polimorfismo cosa?
Page 87: Polimorfismo cosa?

import scalaz.std.set._

implicit def setSemigroup[A]:Semigroup[Set[A]] = new Semigroup[Set[A]] { def append(f1: Set[A], f2: => Set[A]) = f1 ++ f2 }

Page 88: Polimorfismo cosa?

implicit def setSemigroup[A]:Semigroup[Set[A]] = new Semigroup[Set[A]] { def append(f1: Set[A], f2: => Set[A]) = f1 ++ f2 }

op

Page 89: Polimorfismo cosa?

import scalaz.syntax.semigroup._import scalaz.std.list._

List(1, 2) |+| List(3, 4)

res: List[Int] = List(1, 2, 3, 4)

import scalaz.syntax.semigroup._import scalaz.std.set._

Set(1, 2) |+| Set(2, 3)

res: Set[Int] = Set(1, 2, 3)

Page 90: Polimorfismo cosa?

import scalaz.syntax.semigroup._import scalaz.std.anyVal._

1 |+| 2 |+| 3

res: Int = 6

import scalaz.syntax.semigroup._import scalaz.std.string._

"a" |+| "b" |+| "c"

res: String = "abc"

Page 91: Polimorfismo cosa?

/*** A semigroup in type F must satisfy two laws: * * - '''closure''': `∀ a, b in F, append(a, b)` is also in `F`. * - '''associativity''': `∀ a, b, c` in `F`, the equation * `append(append(a, b), c) = append(a, append(b , c))` holds.*/trait SemigroupLaw { def associative(f1: F, f2: F, f3: F)(implicit F: Equal[F]): Boolean = F.equal(append(f1, append(f2, f3)), append(append(f1, f2), f3))}

Page 92: Polimorfismo cosa?

import scalaz.scalacheck.ScalazProperties._import scalaz.std.anyVal._

semigroup.laws[Int].check

+ semigroup.associative: OK, passed 100 tests.

Page 93: Polimorfismo cosa?

semigroup.laws[String].checksemigroup.laws[Set[Int]].checksemigroup.laws[List[String]].checksemigroup.laws[Map[Int, Int]].check

+ semigroup.associative: OK, passed 100 tests.+ semigroup.associative: OK, passed 100 tests.+ semigroup.associative: OK, passed 100 tests.+ semigroup.associative: OK, passed 100 tests.

Page 94: Polimorfismo cosa?

La nostra Map[_, Set[Int]]è un semigruppo?

Page 95: Polimorfismo cosa?

Map("a" -> 1, "b" -> 4) |+| Map("a" -> 2)

res: Map[…] = Map(a -> 3, b -> 4)

“Some data structures form interesting semigroups as long as the types of the elements they contain also form semigroups.”

Page 96: Polimorfismo cosa?

import scalaz.scalacheck.ScalazProperties._

semigroup.laws[Map[String, Set[Int]]].check

+ semigroup.associative: OK, passed 100 tests. ✓

Page 97: Polimorfismo cosa?

Map("a" -> Set(1, 2)) |+| Map("a" -> Set(2, 3))

res: Map[…] = Map(a -> Set(1, 2, 3))

“adattato” da: Functional Programming in Scala - Part 3 - Chapter 10 Monoids

Page 98: Polimorfismo cosa?

Ma nel mio codebasenon ho Map così semplici…

Page 99: Polimorfismo cosa?

Map("a" -> Map("aa" -> Map("aaa" -> Map("aaaa" -> List(1, 3), "aaab" -> List(2, 4))))) |+| Map("a" -> Map("aa" -> Map("aaa" -> Map("aaaa" -> List(5, 7), "aaab" -> List(6, 8)))))

Map(a->Map(aa->Map(aaa->Map(aaaa->List(1, 3, 5, 7), aaab->List(2, 4, 6, 8)))))

Page 100: Polimorfismo cosa?

Benchmarking

Page 101: Polimorfismo cosa?

“Experience indicates that nearly everybody has the wrong idea about the real bottlenecks

in his programs” – Donald Knuth

Computer programming as an art (1974) – http://dl.acm.org/citation.cfm?id=361612

Page 102: Polimorfismo cosa?

Map[String, Set[Int]]

Page 103: Polimorfismo cosa?
Page 104: Polimorfismo cosa?

Settembre 2015

@filippovitale

$ tail -f domande