SlideShare ist ein Scribd-Unternehmen logo
1 von 30
Downloaden Sie, um offline zu lesen
HOW TO EXTEND MAP?
OR WHY WE NEED COLLECTIONS REDESIGN?
SZYMON MATEJCZYK, SCALAR 2017
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
@SZYMONMATEJCZYK
▸ Engineer & data scientist.
▸ Scala fan since 2.8. Graphs lover.
▸ PhD student on leave of absence.
▸ OSS contributor (Cassovary,
Nebulostore).
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
GRID


type Grid[V] = Map[(Int, Int), V]
def row(i: Int): Seq[(Int, V)]
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
SCALA COLLECTIONS
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
SCALA COLLECTIONS - IMMUTABLE
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
IMMUTABLE MAP
package scala

package collection

package immutable



import generic._
trait Map[K, +V] extends Iterable[(K, V)]

// with GenMap[K, V]

with scala.collection.Map[K, V]

with MapLike[K, V, Map[K, V]
trait MapLike[K, +V, +This <: MapLike[K, V, This] with Map[K, V]]

extends scala.collection.MapLike[K, V, This]

with Parallelizable[(K, V), ParMap[K, V]]
package scala

package collection
trait MapLike[K, +V, +This <: MapLike[K, V, This] with Map[K, V]]

extends PartialFunction[K, V]

with IterableLike[(K, V), This]

with GenMapLike[K, V, This]

with Subtractable[K, This]

with Parallelizable[(K, V), ParMap[K, V]]
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
IMMUTABLE.MAP TRAITS HIERARCHY
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
IMMUTABLE MAP
package scala

package collection

package immutable



import generic._
trait Map[K, +V] extends Iterable[(K, V)]

// with GenMap[K, V]

with scala.collection.Map[K, V]

with MapLike[K, V, Map[K, V]
trait MapLike[K, +V, +This <: MapLike[K, V, This] with Map[K, V]]

extends scala.collection.MapLike[K, V, This]

with Parallelizable[(K, V), ParMap[K, V]]
package scala

package collection
trait MapLike[K, +V, +This <: MapLike[K, V, This] with Map[K, V]]

extends PartialFunction[K, V]

with IterableLike[(K, V), This]

with GenMapLike[K, V, This]

with Subtractable[K, This]

with Parallelizable[(K, V), ParMap[K, V]]
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
LET’S START WITH A INTERFACE…
trait Grid[V] extends immutable.Map[(Int, Int), V] {

def row(i: Int): Seq[(Int, V)]

}
class NestedGrid[V](
val underlying: immutable.Map[Int, immutable.Map[Int, V]]
)

extends Grid[V] {
...
}
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
IMPLEMENTATION
override def row(i: Int): Seq[(Int, V)] =
underlying.get(i).toSeq.flatten



override def get(key: (Int, Int)): Option[V] = {

for {

inner <- underlying.get(key._1)

res <- inner.get(key._2)

} yield res

}
override def iterator: Iterator[((Int, Int), V)] =
underlying.iterator.flatMap{

case (first, map) => map.iterator.map(x => ((first, x._1), x._2))

}



override def -(key: (Int, Int)): NestedGrid[V] = {

underlying.get(key._1) match {

case Some(e) => new NestedGrid(underlying + ((key._1, e - key._2)))

case None => this

}

}
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
IMPLEMENTATION
class NestedGrid[V](
val underlying: immutable.Map[Int, immutable.Map[Int, V]]
) extends Grid[V] {
override def +(kv: ((Int, Int), V)): NestedGrid[V] = {

...
}
}
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
IMPLEMENTATION
class NestedGrid[V](
val underlying: immutable.Map[Int, immutable.Map[Int, V]]
) extends Grid[V] {
override def +(kv: ((Int, Int), V)): NestedGrid[V] = {

...
}
}
Method + overrides nothing
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
FEW STEPS BACK
trait Grid[+V] extends immutable.Map[(Int, Int), V] {

def row(i: Int): Seq[(Int, V)]

}





class NestedGrid[+V](
protected val underlying: immutable.Map[Int, immutable.Map[Int, V]]
)

extends Grid[V]

{
override def +[V1 >: V](kv: ((Int, Int), V1)): NestedGrid[V1] = {

...
}
}
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
IMPLEMENTATION CONT’D




override def +[V1 >: V](kv: ((Int, Int), V1)): NestedGrid[V1] = {

underlying.get(kv._1._1) match {

case Some(e) => new NestedGrid(

underlying + ((kv._1._1, e + ((kv._1._1, kv._2))))

)

case None => new NestedGrid(

underlying + ((kv._1._1, immutable.Map(kv._1._2 -> kv._2)))

)

}

}
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
IMMUTABLE MAP COVARIANCE
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
SIMPLE
trait Key

case class DoorKey(id: Int) extends Key

case class EnglishKey(size: Int) extends Key



import scala.collection.immutable.Map



val cabinet = Map[Int, DoorKey](

1 -> DoorKey(7),

3 -> DoorKey(8)

)



cabinet + (5 -> EnglishKey(77))

HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
IMMUTABLE MAP COVARIANCE
=+
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
TEST
def sampleMap = {

val map: NestedGrid[Figure] = NestedGrid.empty[Figure]

map + (((1, 1), Bishop)) + (((2, 2), Knight))

}


"Grid" should {

"contain elements" in {

val map = sampleMap

map((1, 1)) should equal (Bishop)

map.toSeq.sortBy(_._1) should equal (Seq(

((1, 1), Bishop),

((2, 2), Knight)

))

}



"support iteration" in {

val map = sampleMap

map.iterator.toSeq should equal (Seq(((1, 1), Bishop), ((2, 2), Knight)))

}



"support adding superclass" in {

val map: NestedGrid[Figure] = NestedGrid.empty[Figure]

(map + (((2, 2), Pawn))) shouldBe an[Grid[Piece]]

}



"support row-iteration" in {

val map = sampleMap

map.row(1) should equal (Seq((1, Bishop)))

}

}
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
FILTER AND OTHERS
def filter(p: A => Boolean): Repr = {

val b = newBuilder

for (x <- this)

if (p(x)) b += x

b.result

}
trait Map[K, +V] extends ...

with MapLike[K, V, Map[K, V]
trait MapLike[K, +V, +This <: MapLike[K, V, This] extends … {
override protected[this] def newBuilder: Builder[(K, V), This] =
new MapBuilder[K, V, This](empty)
}
class NestedGrid[+V](
protected val underlying: immutable.Map[Int, immutable.Map[Int, V]]
)

extends Grid[V]

with immutable.MapLike[(Int, Int), V, NestedGrid[V]]
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
MAP AND OTHERS
def map[B, That](f: A => B)(
implicit bf: CanBuildFrom[Repr, B, That]
): That = {

val b = bf(repr)
b.sizeHint(this)

for (x <- this) b += f(x)

b.result

}
implicit def canBuildFrom[B]: CanBuildFrom[NestedGrid[B], ((Int, Int), B), NestedGrid[B]] =

new CanBuildFrom[NestedGrid[_], ((Int, Int), B), NestedGrid[B]] {

override def apply(from: NestedGrid[_]): mutable.Builder[((Int, Int), B), NestedGrid[B]] =

newBuilder[B]

override def apply(): mutable.Builder[((Int, Int), B), NestedGrid[B]] = newBuilder

}
def newBuilder[B]: mutable.Builder[((Int, Int), B), NestedGrid[B]] =

new mutable.MapBuilder[(Int, Int), B, NestedGrid[B]](empty)
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
DEFAULT
override def withDefault[V1 >: V](d: ((Int, Int)) => V1): NestedGrid[V1] =
new NestedGrid.WithDefault[V1](this, d)



override def withDefaultValue[V1 >: V](d: V1): NestedGrid[V1] =
new NestedGrid.WithDefault[V1](this, x => d)
class WithDefault[+V](from: NestedGrid[V], d: ((Int, Int)) => V) extends NestedGrid[V](from.underlying) {

override def empty = new WithDefault(from.empty, d)

override def updated[V1 >: V](key: (Int, Int), value: V1): WithDefault[V1] =

new WithDefault[V1](from.updated[V1](key, value), d)

override def + [V1 >: V](kv: ((Int, Int), V1)): WithDefault[V1] = updated(kv._1, kv ._2)

override def - (key: (Int, Int)): WithDefault[V] = new WithDefault(from - key, d)

override def withDefault[V1 >: V](d: ((Int, Int)) => V1): NestedGrid[V1] = new WithDefault[V1](from, d)

override def withDefaultValue[V1 >: V](d: V1): NestedGrid[V1] = new WithDefault[V1](from, x => d)

override def default(x: (Int, Int)) = d(x)

}
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
RECAP
1. Decipher hierarchy
2. Implement logic
3. Be careful about variance and type bounds.
4. Change type params in MapLike for filter, take,…
5. Add implicit CanBuildFrom for map, flatMap, …
6. Manually create WithDefault implementation
(code duplication)
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
COLLECTIONS REDESIGN (ODERSKY)
•simplicity
•separate interface from implementation
•fix complicated inheritance structure
•improve efficiency
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
COLLECTIONS REDESIGN (SPIEWAK)
•to generic interfaces (Seq)
•collection/mutable/immutable
•general implementations inefficient
•extendability is important
•CanBuildFrom does more harm than good
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
BONUS - QUESTIONS
Did you spot a memory leak?
How would experienced Scala programmer tackle the
problem?
Is the extension of mutable.Map similar?
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
BONUS - ALTERNATIVES
•Implement row method outside of Map
•Implicit conversions
•Use composition, implement map, filter, default … on your
own
HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
REFERENCES
•http://www.artima.com/scalazine/articles/scala_collections_architecture.html
•https://github.com/lampepfl/dotty/issues/818
•https://gist.github.com/djspiewak/2ae2570c8856037a7738
•Code: https://github.com/szymonm/scalar-grid
•@szymonmatejczyk

Weitere ähnliche Inhalte

Was ist angesagt?

Data made out of functions
Data made out of functionsData made out of functions
Data made out of functionskenbot
 
Cbse question paper class_xii_paper_2000
Cbse question paper class_xii_paper_2000Cbse question paper class_xii_paper_2000
Cbse question paper class_xii_paper_2000Deepak Singh
 
Fp in scala with adts
Fp in scala with adtsFp in scala with adts
Fp in scala with adtsHang Zhao
 
Introduction to Monads in Scala (2)
Introduction to Monads in Scala (2)Introduction to Monads in Scala (2)
Introduction to Monads in Scala (2)stasimus
 
All You Need is Fold
All You Need is FoldAll You Need is Fold
All You Need is FoldMike Harris
 
COMPUTER GRAPHICS LAB MANUAL
COMPUTER GRAPHICS LAB MANUALCOMPUTER GRAPHICS LAB MANUAL
COMPUTER GRAPHICS LAB MANUALVivek Kumar Sinha
 
Computer graphics lab manual
Computer graphics lab manualComputer graphics lab manual
Computer graphics lab manualUma mohan
 
Computer Graphics in Java and Scala - Part 1b
Computer Graphics in Java and Scala - Part 1bComputer Graphics in Java and Scala - Part 1b
Computer Graphics in Java and Scala - Part 1bPhilip Schwarz
 
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...Philip Schwarz
 
Computer graphics
Computer graphics Computer graphics
Computer graphics shafiq sangi
 
LAC2013 UNIT preTESTs!
LAC2013 UNIT preTESTs!LAC2013 UNIT preTESTs!
LAC2013 UNIT preTESTs!A Jorge Garcia
 
All You Need is Fold in the Key of C#
All You Need is Fold in the Key of C#All You Need is Fold in the Key of C#
All You Need is Fold in the Key of C#Mike Harris
 
Programs in array using SWIFT
Programs in array using SWIFTPrograms in array using SWIFT
Programs in array using SWIFTvikram mahendra
 
SE Computer, Programming Laboratory(210251) University of Pune
SE Computer, Programming Laboratory(210251) University of PuneSE Computer, Programming Laboratory(210251) University of Pune
SE Computer, Programming Laboratory(210251) University of PuneBhavesh Shah
 
Seminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov Vyacheslav
Seminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov VyacheslavSeminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov Vyacheslav
Seminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov VyacheslavVyacheslav Arbuzov
 

Was ist angesagt? (20)

Data made out of functions
Data made out of functionsData made out of functions
Data made out of functions
 
Cbse question paper class_xii_paper_2000
Cbse question paper class_xii_paper_2000Cbse question paper class_xii_paper_2000
Cbse question paper class_xii_paper_2000
 
Fp in scala with adts
Fp in scala with adtsFp in scala with adts
Fp in scala with adts
 
Advance java
Advance javaAdvance java
Advance java
 
Introduction to Monads in Scala (2)
Introduction to Monads in Scala (2)Introduction to Monads in Scala (2)
Introduction to Monads in Scala (2)
 
All You Need is Fold
All You Need is FoldAll You Need is Fold
All You Need is Fold
 
COMPUTER GRAPHICS LAB MANUAL
COMPUTER GRAPHICS LAB MANUALCOMPUTER GRAPHICS LAB MANUAL
COMPUTER GRAPHICS LAB MANUAL
 
Computer graphics lab manual
Computer graphics lab manualComputer graphics lab manual
Computer graphics lab manual
 
Seminar PSU 10.10.2014 mme
Seminar PSU 10.10.2014 mmeSeminar PSU 10.10.2014 mme
Seminar PSU 10.10.2014 mme
 
Computer Graphics in Java and Scala - Part 1b
Computer Graphics in Java and Scala - Part 1bComputer Graphics in Java and Scala - Part 1b
Computer Graphics in Java and Scala - Part 1b
 
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for fun and profit - Haskell and...
 
Scala.io
Scala.ioScala.io
Scala.io
 
Computer graphics
Computer graphics Computer graphics
Computer graphics
 
LAC2013 UNIT preTESTs!
LAC2013 UNIT preTESTs!LAC2013 UNIT preTESTs!
LAC2013 UNIT preTESTs!
 
All You Need is Fold in the Key of C#
All You Need is Fold in the Key of C#All You Need is Fold in the Key of C#
All You Need is Fold in the Key of C#
 
Programs in array using SWIFT
Programs in array using SWIFTPrograms in array using SWIFT
Programs in array using SWIFT
 
Ml all programs
Ml all programsMl all programs
Ml all programs
 
Perm winter school 2014.01.31
Perm winter school 2014.01.31Perm winter school 2014.01.31
Perm winter school 2014.01.31
 
SE Computer, Programming Laboratory(210251) University of Pune
SE Computer, Programming Laboratory(210251) University of PuneSE Computer, Programming Laboratory(210251) University of Pune
SE Computer, Programming Laboratory(210251) University of Pune
 
Seminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov Vyacheslav
Seminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov VyacheslavSeminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov Vyacheslav
Seminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov Vyacheslav
 

Ähnlich wie How to extend map? Or why we need collections redesign? - Scalar 2017

Will it Blend? - ScalaSyd February 2015
Will it Blend? - ScalaSyd February 2015Will it Blend? - ScalaSyd February 2015
Will it Blend? - ScalaSyd February 2015Filippo Vitale
 
Create a java project that - Draw a circle with three random init.pdf
Create a java project that - Draw a circle with three random init.pdfCreate a java project that - Draw a circle with three random init.pdf
Create a java project that - Draw a circle with three random init.pdfarihantmobileselepun
 
Modular Module Systems
Modular Module SystemsModular Module Systems
Modular Module Systemsleague
 
Monadologie
MonadologieMonadologie
Monadologieleague
 
R + Hadoop = Big Data Analytics. How Revolution Analytics' RHadoop Project Al...
R + Hadoop = Big Data Analytics. How Revolution Analytics' RHadoop Project Al...R + Hadoop = Big Data Analytics. How Revolution Analytics' RHadoop Project Al...
R + Hadoop = Big Data Analytics. How Revolution Analytics' RHadoop Project Al...Revolution Analytics
 
ECMAScript 6 major changes
ECMAScript 6 major changesECMAScript 6 major changes
ECMAScript 6 major changeshayato
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patternsleague
 
package chapter15;import javafx.application.Application;import j.pdf
package chapter15;import javafx.application.Application;import j.pdfpackage chapter15;import javafx.application.Application;import j.pdf
package chapter15;import javafx.application.Application;import j.pdfKARTIKINDIA
 
User Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryUser Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryDatabricks
 
User Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryUser Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryDatabricks
 
How would you implement a node classs and an edge class to create .pdf
How would you implement a node classs and an edge class to create .pdfHow would you implement a node classs and an edge class to create .pdf
How would you implement a node classs and an edge class to create .pdfinfo309708
 
Grokking Monads in Scala
Grokking Monads in ScalaGrokking Monads in Scala
Grokking Monads in ScalaTim Dalton
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsJohn De Goes
 
Data Structures in javaScript 2015
Data Structures in javaScript 2015Data Structures in javaScript 2015
Data Structures in javaScript 2015Nir Kaufman
 
Let’s Talk About Ruby
Let’s Talk About RubyLet’s Talk About Ruby
Let’s Talk About RubyIan Bishop
 
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
 

Ähnlich wie How to extend map? Or why we need collections redesign? - Scalar 2017 (20)

Will it Blend? - ScalaSyd February 2015
Will it Blend? - ScalaSyd February 2015Will it Blend? - ScalaSyd February 2015
Will it Blend? - ScalaSyd February 2015
 
Create a java project that - Draw a circle with three random init.pdf
Create a java project that - Draw a circle with three random init.pdfCreate a java project that - Draw a circle with three random init.pdf
Create a java project that - Draw a circle with three random init.pdf
 
Modular Module Systems
Modular Module SystemsModular Module Systems
Modular Module Systems
 
Monadologie
MonadologieMonadologie
Monadologie
 
R + Hadoop = Big Data Analytics. How Revolution Analytics' RHadoop Project Al...
R + Hadoop = Big Data Analytics. How Revolution Analytics' RHadoop Project Al...R + Hadoop = Big Data Analytics. How Revolution Analytics' RHadoop Project Al...
R + Hadoop = Big Data Analytics. How Revolution Analytics' RHadoop Project Al...
 
ECMAScript 6 major changes
ECMAScript 6 major changesECMAScript 6 major changes
ECMAScript 6 major changes
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patterns
 
package chapter15;import javafx.application.Application;import j.pdf
package chapter15;import javafx.application.Application;import j.pdfpackage chapter15;import javafx.application.Application;import j.pdf
package chapter15;import javafx.application.Application;import j.pdf
 
User Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryUser Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love Story
 
User Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryUser Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love Story
 
How would you implement a node classs and an edge class to create .pdf
How would you implement a node classs and an edge class to create .pdfHow would you implement a node classs and an edge class to create .pdf
How would you implement a node classs and an edge class to create .pdf
 
Grokking Monads in Scala
Grokking Monads in ScalaGrokking Monads in Scala
Grokking Monads in Scala
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
 
SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
 
Data Structures in javaScript 2015
Data Structures in javaScript 2015Data Structures in javaScript 2015
Data Structures in javaScript 2015
 
NumPy Refresher
NumPy RefresherNumPy Refresher
NumPy Refresher
 
Coding in Style
Coding in StyleCoding in Style
Coding in Style
 
Let’s Talk About Ruby
Let’s Talk About RubyLet’s Talk About Ruby
Let’s Talk About Ruby
 
An introduction to scala
An introduction to scalaAn introduction to scala
An introduction to scala
 
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
 

Kürzlich hochgeladen

Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsSafe Software
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Angel Borroy López
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Mater
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprisepreethippts
 
cpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptcpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptrcbcrtm
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 

Kürzlich hochgeladen (20)

Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data Streams
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprise
 
cpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptcpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.ppt
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 

How to extend map? Or why we need collections redesign? - Scalar 2017

  • 1. HOW TO EXTEND MAP? OR WHY WE NEED COLLECTIONS REDESIGN? SZYMON MATEJCZYK, SCALAR 2017
  • 2. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? @SZYMONMATEJCZYK ▸ Engineer & data scientist. ▸ Scala fan since 2.8. Graphs lover. ▸ PhD student on leave of absence. ▸ OSS contributor (Cassovary, Nebulostore).
  • 3. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? GRID 
 type Grid[V] = Map[(Int, Int), V] def row(i: Int): Seq[(Int, V)]
  • 4. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? SCALA COLLECTIONS
  • 5. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? SCALA COLLECTIONS - IMMUTABLE
  • 6. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? IMMUTABLE MAP package scala
 package collection
 package immutable
 
 import generic._ trait Map[K, +V] extends Iterable[(K, V)]
 // with GenMap[K, V]
 with scala.collection.Map[K, V]
 with MapLike[K, V, Map[K, V] trait MapLike[K, +V, +This <: MapLike[K, V, This] with Map[K, V]]
 extends scala.collection.MapLike[K, V, This]
 with Parallelizable[(K, V), ParMap[K, V]] package scala
 package collection trait MapLike[K, +V, +This <: MapLike[K, V, This] with Map[K, V]]
 extends PartialFunction[K, V]
 with IterableLike[(K, V), This]
 with GenMapLike[K, V, This]
 with Subtractable[K, This]
 with Parallelizable[(K, V), ParMap[K, V]]
  • 7. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? IMMUTABLE.MAP TRAITS HIERARCHY
  • 8. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? IMMUTABLE MAP package scala
 package collection
 package immutable
 
 import generic._ trait Map[K, +V] extends Iterable[(K, V)]
 // with GenMap[K, V]
 with scala.collection.Map[K, V]
 with MapLike[K, V, Map[K, V] trait MapLike[K, +V, +This <: MapLike[K, V, This] with Map[K, V]]
 extends scala.collection.MapLike[K, V, This]
 with Parallelizable[(K, V), ParMap[K, V]] package scala
 package collection trait MapLike[K, +V, +This <: MapLike[K, V, This] with Map[K, V]]
 extends PartialFunction[K, V]
 with IterableLike[(K, V), This]
 with GenMapLike[K, V, This]
 with Subtractable[K, This]
 with Parallelizable[(K, V), ParMap[K, V]]
  • 9. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? LET’S START WITH A INTERFACE… trait Grid[V] extends immutable.Map[(Int, Int), V] {
 def row(i: Int): Seq[(Int, V)]
 } class NestedGrid[V]( val underlying: immutable.Map[Int, immutable.Map[Int, V]] )
 extends Grid[V] { ... }
  • 10. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? IMPLEMENTATION override def row(i: Int): Seq[(Int, V)] = underlying.get(i).toSeq.flatten
 
 override def get(key: (Int, Int)): Option[V] = {
 for {
 inner <- underlying.get(key._1)
 res <- inner.get(key._2)
 } yield res
 } override def iterator: Iterator[((Int, Int), V)] = underlying.iterator.flatMap{
 case (first, map) => map.iterator.map(x => ((first, x._1), x._2))
 }
 
 override def -(key: (Int, Int)): NestedGrid[V] = {
 underlying.get(key._1) match {
 case Some(e) => new NestedGrid(underlying + ((key._1, e - key._2)))
 case None => this
 }
 }
  • 11. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? IMPLEMENTATION class NestedGrid[V]( val underlying: immutable.Map[Int, immutable.Map[Int, V]] ) extends Grid[V] { override def +(kv: ((Int, Int), V)): NestedGrid[V] = {
 ... } }
  • 12. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? IMPLEMENTATION class NestedGrid[V]( val underlying: immutable.Map[Int, immutable.Map[Int, V]] ) extends Grid[V] { override def +(kv: ((Int, Int), V)): NestedGrid[V] = {
 ... } } Method + overrides nothing
  • 13. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? FEW STEPS BACK trait Grid[+V] extends immutable.Map[(Int, Int), V] {
 def row(i: Int): Seq[(Int, V)]
 }
 
 
 class NestedGrid[+V]( protected val underlying: immutable.Map[Int, immutable.Map[Int, V]] )
 extends Grid[V]
 { override def +[V1 >: V](kv: ((Int, Int), V1)): NestedGrid[V1] = {
 ... } }
  • 14. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? IMPLEMENTATION CONT’D 
 
 override def +[V1 >: V](kv: ((Int, Int), V1)): NestedGrid[V1] = {
 underlying.get(kv._1._1) match {
 case Some(e) => new NestedGrid(
 underlying + ((kv._1._1, e + ((kv._1._1, kv._2))))
 )
 case None => new NestedGrid(
 underlying + ((kv._1._1, immutable.Map(kv._1._2 -> kv._2)))
 )
 }
 }
  • 15. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? IMMUTABLE MAP COVARIANCE
  • 16. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? SIMPLE trait Key
 case class DoorKey(id: Int) extends Key
 case class EnglishKey(size: Int) extends Key
 
 import scala.collection.immutable.Map
 
 val cabinet = Map[Int, DoorKey](
 1 -> DoorKey(7),
 3 -> DoorKey(8)
 )
 
 cabinet + (5 -> EnglishKey(77))

  • 17. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? IMMUTABLE MAP COVARIANCE =+
  • 18. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? TEST def sampleMap = {
 val map: NestedGrid[Figure] = NestedGrid.empty[Figure]
 map + (((1, 1), Bishop)) + (((2, 2), Knight))
 } 
 "Grid" should {
 "contain elements" in {
 val map = sampleMap
 map((1, 1)) should equal (Bishop)
 map.toSeq.sortBy(_._1) should equal (Seq(
 ((1, 1), Bishop),
 ((2, 2), Knight)
 ))
 }
 
 "support iteration" in {
 val map = sampleMap
 map.iterator.toSeq should equal (Seq(((1, 1), Bishop), ((2, 2), Knight)))
 }
 
 "support adding superclass" in {
 val map: NestedGrid[Figure] = NestedGrid.empty[Figure]
 (map + (((2, 2), Pawn))) shouldBe an[Grid[Piece]]
 }
 
 "support row-iteration" in {
 val map = sampleMap
 map.row(1) should equal (Seq((1, Bishop)))
 }
 }
  • 19. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? FILTER AND OTHERS def filter(p: A => Boolean): Repr = {
 val b = newBuilder
 for (x <- this)
 if (p(x)) b += x
 b.result
 } trait Map[K, +V] extends ...
 with MapLike[K, V, Map[K, V] trait MapLike[K, +V, +This <: MapLike[K, V, This] extends … { override protected[this] def newBuilder: Builder[(K, V), This] = new MapBuilder[K, V, This](empty) } class NestedGrid[+V]( protected val underlying: immutable.Map[Int, immutable.Map[Int, V]] )
 extends Grid[V]
 with immutable.MapLike[(Int, Int), V, NestedGrid[V]]
  • 20. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? MAP AND OTHERS def map[B, That](f: A => B)( implicit bf: CanBuildFrom[Repr, B, That] ): That = {
 val b = bf(repr) b.sizeHint(this)
 for (x <- this) b += f(x)
 b.result
 } implicit def canBuildFrom[B]: CanBuildFrom[NestedGrid[B], ((Int, Int), B), NestedGrid[B]] =
 new CanBuildFrom[NestedGrid[_], ((Int, Int), B), NestedGrid[B]] {
 override def apply(from: NestedGrid[_]): mutable.Builder[((Int, Int), B), NestedGrid[B]] =
 newBuilder[B]
 override def apply(): mutable.Builder[((Int, Int), B), NestedGrid[B]] = newBuilder
 } def newBuilder[B]: mutable.Builder[((Int, Int), B), NestedGrid[B]] =
 new mutable.MapBuilder[(Int, Int), B, NestedGrid[B]](empty)
  • 21. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? DEFAULT override def withDefault[V1 >: V](d: ((Int, Int)) => V1): NestedGrid[V1] = new NestedGrid.WithDefault[V1](this, d)
 
 override def withDefaultValue[V1 >: V](d: V1): NestedGrid[V1] = new NestedGrid.WithDefault[V1](this, x => d) class WithDefault[+V](from: NestedGrid[V], d: ((Int, Int)) => V) extends NestedGrid[V](from.underlying) {
 override def empty = new WithDefault(from.empty, d)
 override def updated[V1 >: V](key: (Int, Int), value: V1): WithDefault[V1] =
 new WithDefault[V1](from.updated[V1](key, value), d)
 override def + [V1 >: V](kv: ((Int, Int), V1)): WithDefault[V1] = updated(kv._1, kv ._2)
 override def - (key: (Int, Int)): WithDefault[V] = new WithDefault(from - key, d)
 override def withDefault[V1 >: V](d: ((Int, Int)) => V1): NestedGrid[V1] = new WithDefault[V1](from, d)
 override def withDefaultValue[V1 >: V](d: V1): NestedGrid[V1] = new WithDefault[V1](from, x => d)
 override def default(x: (Int, Int)) = d(x)
 }
  • 22. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? RECAP 1. Decipher hierarchy 2. Implement logic 3. Be careful about variance and type bounds. 4. Change type params in MapLike for filter, take,… 5. Add implicit CanBuildFrom for map, flatMap, … 6. Manually create WithDefault implementation (code duplication)
  • 23.
  • 24. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
  • 25. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? COLLECTIONS REDESIGN (ODERSKY) •simplicity •separate interface from implementation •fix complicated inheritance structure •improve efficiency
  • 26. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN?
  • 27. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? COLLECTIONS REDESIGN (SPIEWAK) •to generic interfaces (Seq) •collection/mutable/immutable •general implementations inefficient •extendability is important •CanBuildFrom does more harm than good
  • 28. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? BONUS - QUESTIONS Did you spot a memory leak? How would experienced Scala programmer tackle the problem? Is the extension of mutable.Map similar?
  • 29. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? BONUS - ALTERNATIVES •Implement row method outside of Map •Implicit conversions •Use composition, implement map, filter, default … on your own
  • 30. HOW TO EXTEND MAP?… OR WHY WE NEED COLLECTIONS REDESIGN? REFERENCES •http://www.artima.com/scalazine/articles/scala_collections_architecture.html •https://github.com/lampepfl/dotty/issues/818 •https://gist.github.com/djspiewak/2ae2570c8856037a7738 •Code: https://github.com/szymonm/scalar-grid •@szymonmatejczyk