SlideShare a Scribd company logo
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

More Related Content

What's hot

Data made out of functions
Data made out of functionsData made out of functions
Data made out of functions
kenbot
 
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
Deepak Singh
 
Fp in scala with adts
Fp in scala with adtsFp in scala with adts
Fp in scala with adts
Hang Zhao
 
Advance java
Advance javaAdvance java
Advance java
Vivek Kumar Sinha
 
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 Fold
Mike Harris
 
COMPUTER GRAPHICS LAB MANUAL
COMPUTER GRAPHICS LAB MANUALCOMPUTER GRAPHICS LAB MANUAL
COMPUTER GRAPHICS LAB MANUAL
Vivek Kumar Sinha
 
Computer graphics lab manual
Computer graphics lab manualComputer graphics lab manual
Computer graphics lab manual
Uma mohan
 
Seminar PSU 10.10.2014 mme
Seminar PSU 10.10.2014 mmeSeminar PSU 10.10.2014 mme
Seminar PSU 10.10.2014 mme
Vyacheslav Arbuzov
 
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
Philip 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
 
Scala.io
Scala.ioScala.io
Scala.io
Steve Gury
 
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 SWIFT
vikram mahendra
 
Ml all programs
Ml all programsMl all programs
Ml all programs
adnaanmohamed
 
Perm winter school 2014.01.31
Perm winter school 2014.01.31Perm winter school 2014.01.31
Perm winter school 2014.01.31
Vyacheslav Arbuzov
 
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
Bhavesh 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 Vyacheslav
Vyacheslav Arbuzov
 

What's hot (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
 

Similar to 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 2015
Filippo 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.pdf
arihantmobileselepun
 
Modular Module Systems
Modular Module SystemsModular Module Systems
Modular Module Systems
league
 
Monadologie
MonadologieMonadologie
Monadologie
league
 
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 changes
hayato
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patterns
league
 
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
KARTIKINDIA
 
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
Databricks
 
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
Databricks
 
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
info309708
 
Grokking Monads in Scala
Grokking Monads in ScalaGrokking Monads in Scala
Grokking Monads in Scala
Tim 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 & Analytics
John De Goes
 
SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
Christian Baranowski
 
Data Structures in javaScript 2015
Data Structures in javaScript 2015Data Structures in javaScript 2015
Data Structures in javaScript 2015
Nir Kaufman
 
NumPy Refresher
NumPy RefresherNumPy Refresher
NumPy Refresher
Lukasz Dobrzanski
 
Coding in Style
Coding in StyleCoding in Style
Coding in Style
scalaconfjp
 
Let’s Talk About Ruby
Let’s Talk About RubyLet’s Talk About Ruby
Let’s Talk About Ruby
Ian Bishop
 
An introduction to scala
An introduction to scalaAn introduction to scala
An introduction to scala
Mohsen Zainalpour
 
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
SeniorDevOnly
 

Similar to 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
 

Recently uploaded

Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
NYGGS Automation Suite
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
Rakesh Kumar R
 
Webinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for EmbeddedWebinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for Embedded
ICS
 
Oracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptxOracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptx
Remote DBA Services
 
socradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdfsocradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdf
SOCRadar
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
Boni García
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
rickgrimesss22
 
SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024
Hironori Washizaki
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
Fermin Galan
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CDKuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
rodomar2
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Crescat
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
Alina Yurenko
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
Aftab Hussain
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
TheSMSPoint
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
Shane Coughlan
 
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
kalichargn70th171
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
Philip Schwarz
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
Deuglo Infosystem Pvt Ltd
 

Recently uploaded (20)

Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
 
Webinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for EmbeddedWebinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for Embedded
 
Oracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptxOracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptx
 
socradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdfsocradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdf
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
 
SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CDKuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
 
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
Why Mobile App Regression Testing is Critical for Sustained Success_ A Detail...
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
 

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