SlideShare ist ein Scribd-Unternehmen logo
1 von 51
Downloaden Sie, um offline zu lesen
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

Weitere Àhnliche Inhalte

Ähnlich wie 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
 
Itsjustangular
ItsjustangularItsjustangular
Itsjustangularcagataycivici
 
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
 

Ähnlich wie 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
 

Mehr von 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
 
Mobile Testing at Gilt
Mobile Testing at GiltMobile Testing at Gilt
Mobile Testing at GiltGilt 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
 
Virtualization at Gilt
Virtualization at GiltVirtualization at Gilt
Virtualization at GiltGilt Tech Talks
 

Mehr von 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
 

KĂŒrzlich hochgeladen

Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
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
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
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
 
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
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024The Digital Insurer
 
Navi Mumbai Call Girls đŸ„° 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls đŸ„° 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls đŸ„° 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls đŸ„° 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...apidays
 
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
 
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
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusZilliz
 

KĂŒrzlich hochgeladen (20)

Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
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
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
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
 
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
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
Navi Mumbai Call Girls đŸ„° 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls đŸ„° 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls đŸ„° 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls đŸ„° 8617370543 Service Offer VIP Hot Model
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 
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
 
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...
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 

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