SlideShare uma empresa Scribd logo
1 de 51
Baixar para ler offline
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

Mais conteúdo relacionado

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

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
 
Driverimport java.util.Scanner;A class that keeps a f.pdf
Driverimport java.util.Scanner;A class that keeps a f.pdfDriverimport java.util.Scanner;A class that keeps a f.pdf
Driverimport java.util.Scanner;A class that keeps a f.pdfarihantstoneart
 

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

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
 
C++ L10-Inheritance
C++ L10-InheritanceC++ L10-Inheritance
C++ L10-Inheritance
 
React loadable
React loadableReact loadable
React loadable
 
Driverimport java.util.Scanner;A class that keeps a f.pdf
Driverimport java.util.Scanner;A class that keeps a f.pdfDriverimport java.util.Scanner;A class that keeps a f.pdf
Driverimport java.util.Scanner;A class that keeps a f.pdf
 

Mais 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
 

Mais 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

Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate Agents
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate AgentsRyan Mahoney - Will Artificial Intelligence Replace Real Estate Agents
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate AgentsRyan Mahoney
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 

Último (20)

Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate Agents
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate AgentsRyan Mahoney - Will Artificial Intelligence Replace Real Estate Agents
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate Agents
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 

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