SlideShare una empresa de Scribd logo
1 de 51
Descargar para leer sin conexión
http://image.motortrend.com/f/features/consumer/1301_chevrolet_corvette_60_years_american_icon_part_1/42023018/1961-Chevrolet-Corvette-front.jpg

SCALA SELF-TYPES
Gregor Heine, Gilt Groupe
Lets build a car...
Components
●
●
●
●
●
●
●
●

Engine
Fuel Tank
Wheels
Gearbox
Steering
Accelerator
Clutch
etc...
OK, let's write some interfaces
trait Engine {
def start(): Unit
def stop(): Unit
def isRunning(): Boolean
def fuelType: FuelType
}
trait Car {
def drive(): Unit
def park(): Unit
}
Well actually, in Scala we can also
add some implementation
trait Engine {
private var running = false
def start(): Unit = {
if (!running) println("Engine started")
running = true
}
def stop(): Unit = {
if (running) println("Engine stopped")
running = false
}
def isRunning(): Boolean = running
def fuelType: FuelType
}
trait DieselEngine extends Engine {
override val fuelType = FuelType.Diesel
}
Fine, so how do we put an
Engine into a Car?
First attempt:
Inheritance-based assembly
trait Car extends Engine {
def drive() {
start()
println("Vroom vroom")
}
def park() {
if (isRunning() ) println("Break!")
stop()
}
}
val myCar = new Car extends DieselEngine
Hmm, this isn't great:
A Car is also an Engine
:(
This should really be a has-a relation,
right?
Second attempt:
Composition-based assembly
trait Car {
def engine : Engine
def drive() {
engine.start()
println("Vroom vroom")
}
def park() {
if (engine.isRunning() ) println("Break!")
engine.stop()
}
}
val myCar = new Car {
override val engine = new DieselEngine()
}
Hmm OK, a Car has an Engine.
That's better.
But...
There is no guarantee that the
Engine in myCar isn't used in
another Car!
:(
If only there was a way to "mix-in" an
Engine into my car rather than supplying
it from the outside
Enter: self-types
“A self type of a trait is the assumed type of this,
the receiver, to be used within the trait. Any
concrete class that mixes in the trait must ensure
that its type conforms to the trait’s self type.”
Programming in Scala
Erm, what, what, what?
Fine, let's look at an example:
trait Car {
this: Engine => // self-type
def drive() {
start()
println("Vroom vroom")
}
def park() {
println("Break!")
stop()
}

}
object MyCar extends Car with DieselEngine
trait Car {
this: Engine => // self-type
def drive() {

Looks a bit like composition-based assembly

start()
println("Vroom vroom")
}
def park() {
println("Break!")
stop()
}

Looks like inheritance-based assembly

}
object MyCar extends Car with DieselEngine
So what's happening here?
● Self-types are used with traits
● Explicitly declare the type of the value this
● Specify the requirements on any concrete class
or instance the trait is mixed into.
● Declare a dependency of the trait on another
type: “In order to use me you have to be one of
those”
So, tell me more about self-types
No need to call the self-type "this"
You can use this-aliasing to give it a
different name:
trait Car {
engine: Engine =>
def drive() {
engine.start()
println("Vroom vroom")
}
}

Useful for nested classes or traits, where accessing
a particular this would otherwise be difficult
Self-types don’t automatically inherit:
trait HondaCar extends Car
// error: self-type HondaCar does not conform to Car's selftype Car
with Engine

Need to repeat the self-type in subtypes:
trait HondaCar extends Car {
this: Engine =>
// ...
}
A self-type can require multiple types:
trait Car {
this: Engine with FuelTank with GearBox =>
// ...
}

Used when the trait has multiple dependencies
The self-type can be a structural type:
trait Car {
this: {
def start: Unit
def stop: Unit
} =>
// ...
}

Allows for safe mixins with duck-typing.
(Useful when interacting with external dependencies)
So all is good with self-types?
Hmm, well no:
val myCar = new Car extends DieselEngine {}

myCar is still a Car and an Engine
:(
So here's a quick fix:
val myCar: Car = new Car extends DieselEngine {}

… but that's cheating (a bit)!
And it doesn't work for singletons:
object MyCar extends Car with DieselEngine
What we need is a way to wire up and assemble
our components without changing their identity
Enter: The Cake Pattern
Ok, so here's the recipe:
For each component in our system, supply a
Component trait, that declares:
● Any dependent components, using self-types
● A trait describing the component's interface
● An abstract val that will be instantiated with
an instance of the component
● Optionally, implementations of the
component interface
trait EngineComponent {
trait Engine {
private var running = false
def start(): Unit = { /* as before */ }
def stop(): Unit = {/* as before */ }
def isRunning: Boolean = running
def fuelType: FuelType
}
protected val engine : Engine
protected class DieselEngine extends Engine {
override val fuelType = FuelType.Diesel
}
}
trait CarComponent {
this: EngineComponent => // gives access to engine
trait Car {
def drive(): Unit
def park(): Unit
}
protected val car: Car
protected class HondaCar extends Car {
override def drive() {
engine.start()
println("Vroom vroom")
}
override def park() { … }
}
}
Great, now let's tie it all together:
(remember a Car has a couple more components beside an Engine)
object App extends CarComponent with EngineComponent with
FuelTankComponent with GearboxComponent {
override protected val engine = new DieselEngine()
override protected val fuelTank = new FuelTank(capacity = 60)
override protected val gearBox = new FiveGearBox()
override val car = new HondaCar()
}
MyApp.car.drive()
MyApp.car.park()
If we want to write a CarTest, we can
provide mock instances for the
components we're not testing:
val testCar = new CarComponent with EngineComponent with FuelTankComponent
with GearboxComponent {
override protected val engine = mock[Engine]

// mock engine

override protected val fuelTank = mock[FuelTank]

// mock tank

override protected val gearBox = new FiveGearBox() // an actual gearbox
override val car = new HondaCar()
}.car
Time to recap
The Cake Pattern
+ Environment specific assembly of components
+ Compile-time checked, typesafe
+ Everything is immutable
+ No external DI descriptor
- Can become hard to read and understand
- May be difficult to configure components
- No control over initialization order
- Self-types prone to fragile base class problem
Remember this:
trait Car {
engine: Engine =>
def drive() { /* start engine */ }
def park() { /* stop engine */ }
}
object MyCar extends Car with DieselEngine

How did they do it?
Let's decompile MyCar.class
> javap com.example.MyCar
Compiled from "Car.scala"
public final class com.example.MyCar extends java.lang.Object{
public static void park();
public static void drive();
public static boolean isRunning();
public static void stop();
public static void start();
/* … */
}

All functions from Car and Engine have been
"lifted" into the top-level class!
Imagine Car and Engine are part of a library that
I'm using to construct MyCar.
Any change to library-private interactions
between these traits are not reflected in MyCar.
class
http://4.bp.blogspot.com/-OHTIQo-k2_k/Tmjkj66eIYI/AAAAAAAACfY/n1Vj1fseVQ0/s1600/Boom.jpg
Ergo:
Be very careful exposing self-types
as part of a library
Fin.
Sources:
●
●
●
●
●
●
●
●
●

M. Odersky, L. Spoon, B. Venners: Programming in Scala, 2nd Edition
C. S. Horstmann: Scala for the Impatient
M. Odersky: Scalable Component Abstractions
http://lampwww.epfl.ch/~odersky/papers/ScalableComponent.pdf
J. Bonér: Real-World Scala: Dependency Injection (DI)
http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di
A Tour of Scala: Explicitly Typed Self References
http://www.scala-lang.org/old/node/124
Cake pattern in depth
http://www.cakesolutions.net/teamblogs/2011/12/19/cake-pattern-in-depth
Dependency Injection In Scala using Self Type Annotations
http://blog.knoldus.com/2013/01/21/dependency-injection-in-scala-using-self-type-annotations
Cake Pattern in Scala / Self type annotations / Explicitly Typed Self References - explained
https://coderwall.com/p/t_rapw
DI in Scala: Cake Pattern pros & cons
http://www.warski.org/blog/2011/04/di-in-scala-cake-pattern-pros-cons

Más contenido relacionado

La actualidad más candente

La actualidad más candente (20)

Os principais serviços de internet
Os principais serviços de internetOs principais serviços de internet
Os principais serviços de internet
 
Programação C - Aula 1
Programação C - Aula 1Programação C - Aula 1
Programação C - Aula 1
 
Transmissão síncrona e assíncrona
Transmissão síncrona e assíncronaTransmissão síncrona e assíncrona
Transmissão síncrona e assíncrona
 
DIGCOMP - competências digitais
DIGCOMP - competências digitaisDIGCOMP - competências digitais
DIGCOMP - competências digitais
 
Introdução a internet
Introdução a internetIntrodução a internet
Introdução a internet
 
Introdução às Telecomunicações
Introdução às TelecomunicaçõesIntrodução às Telecomunicações
Introdução às Telecomunicações
 
Algoritmo - tipos de dados
Algoritmo - tipos de dadosAlgoritmo - tipos de dados
Algoritmo - tipos de dados
 
Conhecendo o WordPress
Conhecendo o WordPressConhecendo o WordPress
Conhecendo o WordPress
 
Computação Pervasiva
Computação PervasivaComputação Pervasiva
Computação Pervasiva
 
Redes de Computadores 2 - Aula 1 - Wireless
Redes de Computadores 2 - Aula 1 - WirelessRedes de Computadores 2 - Aula 1 - Wireless
Redes de Computadores 2 - Aula 1 - Wireless
 
Dispositivos de Entrada e Saída de dados
Dispositivos de Entrada e Saída de dadosDispositivos de Entrada e Saída de dados
Dispositivos de Entrada e Saída de dados
 
Aula03 - protocolo http
Aula03 -  protocolo httpAula03 -  protocolo http
Aula03 - protocolo http
 
Internet
InternetInternet
Internet
 
Minicurso blender
Minicurso blenderMinicurso blender
Minicurso blender
 
Lista de exercicios algoritmos com pseudocodigo
Lista de exercicios   algoritmos com pseudocodigoLista de exercicios   algoritmos com pseudocodigo
Lista de exercicios algoritmos com pseudocodigo
 
Redes de comunicação - TGPSI
Redes de comunicação - TGPSIRedes de comunicação - TGPSI
Redes de comunicação - TGPSI
 
Manual ftgate pro
Manual ftgate proManual ftgate pro
Manual ftgate pro
 
Arquitetura e Manutenção de Computadores
Arquitetura e Manutenção de ComputadoresArquitetura e Manutenção de Computadores
Arquitetura e Manutenção de Computadores
 
Microprocessadores
MicroprocessadoresMicroprocessadores
Microprocessadores
 
Apostila Redes
Apostila RedesApostila Redes
Apostila Redes
 

Similar a Scala Self Types by Gregor Heine, Principal Software Engineer at Gilt

Protocol-Oriented Programming in Swift
Protocol-Oriented Programming in SwiftProtocol-Oriented Programming in Swift
Protocol-Oriented Programming in SwiftOleksandr Stepanov
 
Jan 2017 - a web of applications (angular 2)
Jan 2017 - a web of applications (angular 2)Jan 2017 - a web of applications (angular 2)
Jan 2017 - a web of applications (angular 2)Kasper Reijnders
 
From android/ java to swift (2)
From android/ java to swift (2)From android/ java to swift (2)
From android/ java to swift (2)allanh0526
 
Ku bangkok sw-eng-dp-02_smart_board_strategypattern
Ku bangkok sw-eng-dp-02_smart_board_strategypatternKu bangkok sw-eng-dp-02_smart_board_strategypattern
Ku bangkok sw-eng-dp-02_smart_board_strategypatternভবঘুরে ঝড়
 
Things to consider for testable Code
Things to consider for testable CodeThings to consider for testable Code
Things to consider for testable CodeFrank Kleine
 
(5) c sharp introduction_object_orientation_part_ii
(5) c sharp introduction_object_orientation_part_ii(5) c sharp introduction_object_orientation_part_ii
(5) c sharp introduction_object_orientation_part_iiNico Ludwig
 
Testing Services Effectively
Testing Services Effectively Testing Services Effectively
Testing Services Effectively Alberto Leal
 
Java Microservices with Spring Boot and Spring Cloud - Denver JUG 2019
Java Microservices with Spring Boot and Spring Cloud - Denver JUG 2019Java Microservices with Spring Boot and Spring Cloud - Denver JUG 2019
Java Microservices with Spring Boot and Spring Cloud - Denver JUG 2019Matt Raible
 
#include iostream#include string#include iomanip#inclu.docx
#include iostream#include string#include iomanip#inclu.docx#include iostream#include string#include iomanip#inclu.docx
#include iostream#include string#include iomanip#inclu.docxmayank272369
 
Dependency Injection with Dagger 2 presentation
Dependency Injection with Dagger 2 presentationDependency Injection with Dagger 2 presentation
Dependency Injection with Dagger 2 presentationJT Liew
 
Software Engineer Screening Question - OOP
Software Engineer Screening Question - OOPSoftware Engineer Screening Question - OOP
Software Engineer Screening Question - OOPjason_scorebig
 
(9) cpp abstractions separated_compilation_and_binding_part_ii
(9) cpp abstractions separated_compilation_and_binding_part_ii(9) cpp abstractions separated_compilation_and_binding_part_ii
(9) cpp abstractions separated_compilation_and_binding_part_iiNico Ludwig
 
Session 4 - Object oriented programming with Objective-C (part 2)
Session 4  - Object oriented programming with Objective-C (part 2)Session 4  - Object oriented programming with Objective-C (part 2)
Session 4 - Object oriented programming with Objective-C (part 2)Vu Tran Lam
 
AWS DeepRacer desde cero - Meetup de awsvalencia (2021/08/12)
AWS DeepRacer desde cero - Meetup de awsvalencia (2021/08/12)AWS DeepRacer desde cero - Meetup de awsvalencia (2021/08/12)
AWS DeepRacer desde cero - Meetup de awsvalencia (2021/08/12)Javier Campos Berga
 
Baparekraf Digital Talent Day: Monitoring dan Coaching Penerima Fasilitasi BD...
Baparekraf Digital Talent Day: Monitoring dan Coaching Penerima Fasilitasi BD...Baparekraf Digital Talent Day: Monitoring dan Coaching Penerima Fasilitasi BD...
Baparekraf Digital Talent Day: Monitoring dan Coaching Penerima Fasilitasi BD...DicodingEvent
 
(7) cpp abstractions inheritance_part_ii
(7) cpp abstractions inheritance_part_ii(7) cpp abstractions inheritance_part_ii
(7) cpp abstractions inheritance_part_iiNico Ludwig
 

Similar a Scala Self Types by Gregor Heine, Principal Software Engineer at Gilt (20)

Protocol-Oriented Programming in Swift
Protocol-Oriented Programming in SwiftProtocol-Oriented Programming in Swift
Protocol-Oriented Programming in Swift
 
Jan 2017 - a web of applications (angular 2)
Jan 2017 - a web of applications (angular 2)Jan 2017 - a web of applications (angular 2)
Jan 2017 - a web of applications (angular 2)
 
From android/ java to swift (2)
From android/ java to swift (2)From android/ java to swift (2)
From android/ java to swift (2)
 
JavaScript Core
JavaScript CoreJavaScript Core
JavaScript Core
 
Ku bangkok sw-eng-dp-02_smart_board_strategypattern
Ku bangkok sw-eng-dp-02_smart_board_strategypatternKu bangkok sw-eng-dp-02_smart_board_strategypattern
Ku bangkok sw-eng-dp-02_smart_board_strategypattern
 
Springs
SpringsSprings
Springs
 
Itsjustangular
ItsjustangularItsjustangular
Itsjustangular
 
Things to consider for testable Code
Things to consider for testable CodeThings to consider for testable Code
Things to consider for testable Code
 
(5) c sharp introduction_object_orientation_part_ii
(5) c sharp introduction_object_orientation_part_ii(5) c sharp introduction_object_orientation_part_ii
(5) c sharp introduction_object_orientation_part_ii
 
Testing Services Effectively
Testing Services Effectively Testing Services Effectively
Testing Services Effectively
 
Java Microservices with Spring Boot and Spring Cloud - Denver JUG 2019
Java Microservices with Spring Boot and Spring Cloud - Denver JUG 2019Java Microservices with Spring Boot and Spring Cloud - Denver JUG 2019
Java Microservices with Spring Boot and Spring Cloud - Denver JUG 2019
 
#include iostream#include string#include iomanip#inclu.docx
#include iostream#include string#include iomanip#inclu.docx#include iostream#include string#include iomanip#inclu.docx
#include iostream#include string#include iomanip#inclu.docx
 
Dependency Injection with Dagger 2 presentation
Dependency Injection with Dagger 2 presentationDependency Injection with Dagger 2 presentation
Dependency Injection with Dagger 2 presentation
 
Software Engineer Screening Question - OOP
Software Engineer Screening Question - OOPSoftware Engineer Screening Question - OOP
Software Engineer Screening Question - OOP
 
(9) cpp abstractions separated_compilation_and_binding_part_ii
(9) cpp abstractions separated_compilation_and_binding_part_ii(9) cpp abstractions separated_compilation_and_binding_part_ii
(9) cpp abstractions separated_compilation_and_binding_part_ii
 
Java conventions
Java conventionsJava conventions
Java conventions
 
Session 4 - Object oriented programming with Objective-C (part 2)
Session 4  - Object oriented programming with Objective-C (part 2)Session 4  - Object oriented programming with Objective-C (part 2)
Session 4 - Object oriented programming with Objective-C (part 2)
 
AWS DeepRacer desde cero - Meetup de awsvalencia (2021/08/12)
AWS DeepRacer desde cero - Meetup de awsvalencia (2021/08/12)AWS DeepRacer desde cero - Meetup de awsvalencia (2021/08/12)
AWS DeepRacer desde cero - Meetup de awsvalencia (2021/08/12)
 
Baparekraf Digital Talent Day: Monitoring dan Coaching Penerima Fasilitasi BD...
Baparekraf Digital Talent Day: Monitoring dan Coaching Penerima Fasilitasi BD...Baparekraf Digital Talent Day: Monitoring dan Coaching Penerima Fasilitasi BD...
Baparekraf Digital Talent Day: Monitoring dan Coaching Penerima Fasilitasi BD...
 
(7) cpp abstractions inheritance_part_ii
(7) cpp abstractions inheritance_part_ii(7) cpp abstractions inheritance_part_ii
(7) cpp abstractions inheritance_part_ii
 

Más de Gilt Tech Talks

“Get Stuff Done Faster: Why Engineers Should Work with the ‘Dark Side’ of Tech”
“Get Stuff Done Faster: Why Engineers Should Work with the ‘Dark Side’ of Tech”“Get Stuff Done Faster: Why Engineers Should Work with the ‘Dark Side’ of Tech”
“Get Stuff Done Faster: Why Engineers Should Work with the ‘Dark Side’ of Tech”Gilt Tech Talks
 
Optimizely at Gilt--November 2013 presentation
Optimizely at Gilt--November 2013 presentationOptimizely at Gilt--November 2013 presentation
Optimizely at Gilt--November 2013 presentationGilt Tech Talks
 
The Agile PMO (fall 2014 version)
The Agile PMO (fall 2014 version)The Agile PMO (fall 2014 version)
The Agile PMO (fall 2014 version)Gilt Tech Talks
 
iOS Testing With Appium at Gilt
iOS Testing With Appium at GiltiOS Testing With Appium at Gilt
iOS Testing With Appium at GiltGilt Tech Talks
 
Handling Changes to Your Server-Side Data Model
Handling Changes to Your Server-Side Data ModelHandling Changes to Your Server-Side Data Model
Handling Changes to Your Server-Side Data ModelGilt Tech Talks
 
Beyond the Crystal Ball: The Agile PMO
Beyond the Crystal Ball: The Agile PMOBeyond the Crystal Ball: The Agile PMO
Beyond the Crystal Ball: The Agile PMOGilt Tech Talks
 
Exploring Docker at Gilt
Exploring Docker at GiltExploring Docker at Gilt
Exploring Docker at GiltGilt Tech Talks
 
Scaling Gilt: from monolith ruby app to micro service scala service architecture
Scaling Gilt: from monolith ruby app to micro service scala service architectureScaling Gilt: from monolith ruby app to micro service scala service architecture
Scaling Gilt: from monolith ruby app to micro service scala service architectureGilt Tech Talks
 
PostgreSQL Setup Using Docker
PostgreSQL Setup Using DockerPostgreSQL Setup Using Docker
PostgreSQL Setup Using DockerGilt Tech Talks
 
Roadmap for the Trillion Sensor Universe -- a Gilt-hosted, Internet of Things...
Roadmap for the Trillion Sensor Universe -- a Gilt-hosted, Internet of Things...Roadmap for the Trillion Sensor Universe -- a Gilt-hosted, Internet of Things...
Roadmap for the Trillion Sensor Universe -- a Gilt-hosted, Internet of Things...Gilt Tech Talks
 

Más de Gilt Tech Talks (13)

“Get Stuff Done Faster: Why Engineers Should Work with the ‘Dark Side’ of Tech”
“Get Stuff Done Faster: Why Engineers Should Work with the ‘Dark Side’ of Tech”“Get Stuff Done Faster: Why Engineers Should Work with the ‘Dark Side’ of Tech”
“Get Stuff Done Faster: Why Engineers Should Work with the ‘Dark Side’ of Tech”
 
Optimizely at Gilt--November 2013 presentation
Optimizely at Gilt--November 2013 presentationOptimizely at Gilt--November 2013 presentation
Optimizely at Gilt--November 2013 presentation
 
The Agile PMO (fall 2014 version)
The Agile PMO (fall 2014 version)The Agile PMO (fall 2014 version)
The Agile PMO (fall 2014 version)
 
An Intro to Swift
An Intro to SwiftAn Intro to Swift
An Intro to Swift
 
iOS Testing With Appium at Gilt
iOS Testing With Appium at GiltiOS Testing With Appium at Gilt
iOS Testing With Appium at Gilt
 
Handling Changes to Your Server-Side Data Model
Handling Changes to Your Server-Side Data ModelHandling Changes to Your Server-Side Data Model
Handling Changes to Your Server-Side Data Model
 
Mobile Testing at Gilt
Mobile Testing at GiltMobile Testing at Gilt
Mobile Testing at Gilt
 
Beyond the Crystal Ball: The Agile PMO
Beyond the Crystal Ball: The Agile PMOBeyond the Crystal Ball: The Agile PMO
Beyond the Crystal Ball: The Agile PMO
 
Exploring Docker at Gilt
Exploring Docker at GiltExploring Docker at Gilt
Exploring Docker at Gilt
 
Scaling Gilt: from monolith ruby app to micro service scala service architecture
Scaling Gilt: from monolith ruby app to micro service scala service architectureScaling Gilt: from monolith ruby app to micro service scala service architecture
Scaling Gilt: from monolith ruby app to micro service scala service architecture
 
PostgreSQL Setup Using Docker
PostgreSQL Setup Using DockerPostgreSQL Setup Using Docker
PostgreSQL Setup Using Docker
 
Roadmap for the Trillion Sensor Universe -- a Gilt-hosted, Internet of Things...
Roadmap for the Trillion Sensor Universe -- a Gilt-hosted, Internet of Things...Roadmap for the Trillion Sensor Universe -- a Gilt-hosted, Internet of Things...
Roadmap for the Trillion Sensor Universe -- a Gilt-hosted, Internet of Things...
 
Virtualization at Gilt
Virtualization at GiltVirtualization at Gilt
Virtualization at Gilt
 

Último

How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 

Último (20)

How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 

Scala Self Types by Gregor Heine, Principal Software Engineer at Gilt

  • 2. Lets build a car...
  • 4. OK, let's write some interfaces
  • 5. trait Engine { def start(): Unit def stop(): Unit def isRunning(): Boolean def fuelType: FuelType } trait Car { def drive(): Unit def park(): Unit }
  • 6. Well actually, in Scala we can also add some implementation
  • 7. trait Engine { private var running = false def start(): Unit = { if (!running) println("Engine started") running = true } def stop(): Unit = { if (running) println("Engine stopped") running = false } def isRunning(): Boolean = running def fuelType: FuelType } trait DieselEngine extends Engine { override val fuelType = FuelType.Diesel }
  • 8. Fine, so how do we put an Engine into a Car?
  • 10. trait Car extends Engine { def drive() { start() println("Vroom vroom") } def park() { if (isRunning() ) println("Break!") stop() } } val myCar = new Car extends DieselEngine
  • 11. Hmm, this isn't great: A Car is also an Engine :( This should really be a has-a relation, right?
  • 13. trait Car { def engine : Engine def drive() { engine.start() println("Vroom vroom") } def park() { if (engine.isRunning() ) println("Break!") engine.stop() } } val myCar = new Car { override val engine = new DieselEngine() }
  • 14. Hmm OK, a Car has an Engine. That's better. But...
  • 15. There is no guarantee that the Engine in myCar isn't used in another Car! :(
  • 16. If only there was a way to "mix-in" an Engine into my car rather than supplying it from the outside Enter: self-types
  • 17. “A self type of a trait is the assumed type of this, the receiver, to be used within the trait. Any concrete class that mixes in the trait must ensure that its type conforms to the trait’s self type.” Programming in Scala
  • 18. Erm, what, what, what? Fine, let's look at an example:
  • 19. trait Car { this: Engine => // self-type def drive() { start() println("Vroom vroom") } def park() { println("Break!") stop() } } object MyCar extends Car with DieselEngine
  • 20. trait Car { this: Engine => // self-type def drive() { Looks a bit like composition-based assembly start() println("Vroom vroom") } def park() { println("Break!") stop() } Looks like inheritance-based assembly } object MyCar extends Car with DieselEngine
  • 22. ● Self-types are used with traits ● Explicitly declare the type of the value this ● Specify the requirements on any concrete class or instance the trait is mixed into. ● Declare a dependency of the trait on another type: “In order to use me you have to be one of those”
  • 23. So, tell me more about self-types
  • 24. No need to call the self-type "this" You can use this-aliasing to give it a different name:
  • 25. trait Car { engine: Engine => def drive() { engine.start() println("Vroom vroom") } } Useful for nested classes or traits, where accessing a particular this would otherwise be difficult
  • 26. Self-types don’t automatically inherit: trait HondaCar extends Car // error: self-type HondaCar does not conform to Car's selftype Car with Engine Need to repeat the self-type in subtypes: trait HondaCar extends Car { this: Engine => // ... }
  • 27. A self-type can require multiple types: trait Car { this: Engine with FuelTank with GearBox => // ... } Used when the trait has multiple dependencies
  • 28. The self-type can be a structural type: trait Car { this: { def start: Unit def stop: Unit } => // ... } Allows for safe mixins with duck-typing. (Useful when interacting with external dependencies)
  • 29. So all is good with self-types?
  • 30. Hmm, well no: val myCar = new Car extends DieselEngine {} myCar is still a Car and an Engine :(
  • 31. So here's a quick fix: val myCar: Car = new Car extends DieselEngine {} … but that's cheating (a bit)! And it doesn't work for singletons: object MyCar extends Car with DieselEngine
  • 32. What we need is a way to wire up and assemble our components without changing their identity
  • 33. Enter: The Cake Pattern
  • 34.
  • 35. Ok, so here's the recipe:
  • 36. For each component in our system, supply a Component trait, that declares: ● Any dependent components, using self-types ● A trait describing the component's interface ● An abstract val that will be instantiated with an instance of the component ● Optionally, implementations of the component interface
  • 37. trait EngineComponent { trait Engine { private var running = false def start(): Unit = { /* as before */ } def stop(): Unit = {/* as before */ } def isRunning: Boolean = running def fuelType: FuelType } protected val engine : Engine protected class DieselEngine extends Engine { override val fuelType = FuelType.Diesel } }
  • 38. trait CarComponent { this: EngineComponent => // gives access to engine trait Car { def drive(): Unit def park(): Unit } protected val car: Car protected class HondaCar extends Car { override def drive() { engine.start() println("Vroom vroom") } override def park() { … } } }
  • 39. Great, now let's tie it all together: (remember a Car has a couple more components beside an Engine)
  • 40. object App extends CarComponent with EngineComponent with FuelTankComponent with GearboxComponent { override protected val engine = new DieselEngine() override protected val fuelTank = new FuelTank(capacity = 60) override protected val gearBox = new FiveGearBox() override val car = new HondaCar() } MyApp.car.drive() MyApp.car.park()
  • 41. If we want to write a CarTest, we can provide mock instances for the components we're not testing:
  • 42. val testCar = new CarComponent with EngineComponent with FuelTankComponent with GearboxComponent { override protected val engine = mock[Engine] // mock engine override protected val fuelTank = mock[FuelTank] // mock tank override protected val gearBox = new FiveGearBox() // an actual gearbox override val car = new HondaCar() }.car
  • 44. The Cake Pattern + Environment specific assembly of components + Compile-time checked, typesafe + Everything is immutable + No external DI descriptor - Can become hard to read and understand - May be difficult to configure components - No control over initialization order - Self-types prone to fragile base class problem
  • 45. Remember this: trait Car { engine: Engine => def drive() { /* start engine */ } def park() { /* stop engine */ } } object MyCar extends Car with DieselEngine How did they do it? Let's decompile MyCar.class
  • 46. > javap com.example.MyCar Compiled from "Car.scala" public final class com.example.MyCar extends java.lang.Object{ public static void park(); public static void drive(); public static boolean isRunning(); public static void stop(); public static void start(); /* … */ } All functions from Car and Engine have been "lifted" into the top-level class!
  • 47. Imagine Car and Engine are part of a library that I'm using to construct MyCar. Any change to library-private interactions between these traits are not reflected in MyCar. class
  • 49. Ergo: Be very careful exposing self-types as part of a library
  • 50. Fin.
  • 51. Sources: ● ● ● ● ● ● ● ● ● M. Odersky, L. Spoon, B. Venners: Programming in Scala, 2nd Edition C. S. Horstmann: Scala for the Impatient M. Odersky: Scalable Component Abstractions http://lampwww.epfl.ch/~odersky/papers/ScalableComponent.pdf J. Bonér: Real-World Scala: Dependency Injection (DI) http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di A Tour of Scala: Explicitly Typed Self References http://www.scala-lang.org/old/node/124 Cake pattern in depth http://www.cakesolutions.net/teamblogs/2011/12/19/cake-pattern-in-depth Dependency Injection In Scala using Self Type Annotations http://blog.knoldus.com/2013/01/21/dependency-injection-in-scala-using-self-type-annotations Cake Pattern in Scala / Self type annotations / Explicitly Typed Self References - explained https://coderwall.com/p/t_rapw DI in Scala: Cake Pattern pros & cons http://www.warski.org/blog/2011/04/di-in-scala-cake-pattern-pros-cons