SlideShare a Scribd company logo
KOTLIN -
DSL
About me :)
‣ Roque Buarque Junior
‣ Brazilian
‣ Android Engineer
‣ Berlin - Germany
‣ Sharenow
‣ @roqbjr
KOTLIN - DSL
WHAT YOU WILL SEE?
▸What is DSL?
▸DSL Examples
▸Kotlin features to build a DSL
▸Code
▸Code
▸And more CODE
KOTLIN - DSL
KOTLIN IN ACTION
▸Chapter 11 - DSL Construction
A DOMAIN-SPECIFIC
LANGUAGE (DSL) IS A COMPUTER
LANGUAGE SPECIALIZED TO A
PARTICULAR
APPLICATION DOMAIN. THIS IS IN
CONTRAST TO A GENERAL-
PURPOSE LANGUAGE (GPL),
WHICH IS BROADLY APPLICABLE
ACROSS DOMAINS. From Wikipedia
KOTLIN - DSL
WH
Y?
KOTLIN - DSL
val list = mutableListOf("A", "B", "C").toList()
val list = buildList {
add("A")
add("B")
add("C")
}
KOTLIN - DSL
HIGHER-ORDER FUNCTIONS AND
LAMBDAS
▸Store in variables and data structures
▸Pass as argument to and return from other function
A higher-order function is a function that takes functions as parameters, or returns a function.
KOTLIN - DSL
class Person {
lateinit var name: String
lateinit var email: String
}
KOTLIN - DSL
class Person {
lateinit var name: String
lateinit var email: String
}
val person = Person()
person.name = "Roque"
person.email = "roque@email.com"
SCOP
E
FUNCT
IONS
KOTLIN - DSL
class Person {
lateinit var name: String
lateinit var email: String
}
Person()
.apply {
this.name = "Roque"
this.email = "roque@email.com"
}
KOTLIN - DSL
class Person {
lateinit var name: String
lateinit var email: String
}
Person()
.apply {
name = "Roque"
email = "roque@email.com"
}
KOTLIN - DSL
val helloWorld = "Hello".apply {
"$this World"
}
Hello
KOTLIN - DSL
Person()
.apply {
name = "Roque"
email = "roque@email.com"
}
public inline fun <T> T.apply(block: T.() -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
return this
}
KOTLIN - DSL
Person()
.let {
it.name = "Roque"
it.email = "roque@email.com"
}
KOTLIN - DSL
val helloWorld = "Hello".let {
"$it World"
}
Hello World
KOTLIN - DSL
Person()
.let {
it.name = "Roque"
it.email = "roque@email.com"
}
public inline fun <T, R> T.let(block: (T) -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block(this)
}
KOTLIN - DSL
fun helloWorld(block: () -> Unit) {
println("Hello World")
block()
}
helloWorld{ }
Hello World
KOTLIN - DSL
fun helloWorld(block: (String) -> Unit) {
println("Hello")
block("World")
}
helloWorld{
print(it)
}
Hello
World
KOTLIN - DSL
fun helloWorld(block: String.(String) -> Unit) {
block(“Hello”, “World”)
}
helloWorld{
print(“$this $it”)
}
Hello World
KOTLIN - DSL
fun <T> T.helloWorld(block: T.() -> Unit) {
block(this)
}
"Hello".helloWorld {
print(this)
}
Hello
KOTLIN - DSL
fun <T, R> T.helloWorld(block: T.() -> R) : R {
return block(this)
}
val helloWorld = "Hello".helloWorld {
"$this World"
}
print(helloWorld)
Hello World
KOTLIN - DSL
HTML
<table>
<tr>
<td> cell </td>
</tr>
</table>
KOTLIN - DSL
HTML
"<table>
<tr>
<td> cell </td>
</tr>
</table>"
KOTLIN - DSL
HTML
“<table>
<tr>
<td> cell </td>
</tr>
</table>"
createHTML().
table {
tr {
td { +”cell” }
}
}
https://github.com/Kotlin/kotlinx.html
KOTLIN - DSL
SQL
SELECT *
FROM users
WHERE age = 18
KOTLIN - DSL
SQL
"SELECT *
FROM users
WHERE age = 18”
KOTLIN - DSL
EXPOSED - JETBRAINS
https://github.com/JetBrains/Exposed/
"SELECT *
FROM users
WHERE age = 18”
Users.select {
Users.age eq 18
}
KOTLIN - DSL
SQL
User select { age eq 18 }
INF
IX
KOTLIN - DSL
INFIX
▸Must be member function or extension function
▸Must have only a single parameter
▸The parameter must have no default value
▸The parameter must not accept varargs
▸Receiver and parameter must be specified
Functions marked with the infix keyword can also be called using the infix notation(omitting the dot and the
parentheses for the call)
KOTLIN - DSL
object User {
operator fun invoke(query: String): User {
this.query += query
return this
}
infix fun select(block: User.() -> Unit) {
User("SELECT * FROM users").block()
}
}
KOTLIN - DSL
object User {
private var query = ""
val age: User
get() = this.where("age")
val name: User
get() = this.where("name")
private fun where(field: String): User {
query+= " WHERE $field"
return this
}
infix fun eq(age: Int) {
println("$query = $age")
}
}
KOTLIN - DSL
SQL
User select { age eq 18 }
KOTLIN - DSL
SQL
User select { age eq 18 }
SELECT * FROM users WHERE age = 18
CAKE
DSL
KOTLIN - DSL
CAKE
val cake = Cooker make Cake of Chocolate and Coconut withOut
Sugar forMy Birthday
print(cake)
KOTLIN - DSL
INFIX
class Cooker {
}
KOTLIN - DSL
INFIX
class Cooker {
fun make(value: Dish)
{
. . .
}
}
Cooker().make(Cake())
KOTLIN - DSL
INFIX
class Cooker {
infix fun make(value: Dish)
{
. . .
}
}
Cooker() make Cake()
KOTLIN - DSL
INFIX
object Cooker {
infix fun make(value: Dish)
{
. . .
}
}
Cooker make Cake()
SEALED
CLASS
KOTLIN - DSL
SEALED CLASS
▸Is abstract by itself, cannot be instantiated
▸Not allowed to have non-private constructors (their
constructors are private by default).
Sealed classes are used for representing restricted class hierarchies, when a value can have one of the
types from limited set, but cannot have any other type.
KOTLIN - DSL
SEALED CLASSES
class Ingredients{
}
KOTLIN - DSL
SEALED CLASSES
sealed class Ingredients{
}
KOTLIN - DSL
SEALED CLASSES
sealed class Ingredients{
object Chocolate : Ingredients()
object Coconut : Ingredients()
object Sugar : Ingredients()
}
KOTLIN - DSL
SEALED CLASSES
sealed class Ingredients{
object Chocolate : Ingredients()
object Coconut : Ingredients()
object Sugar : Ingredients()
}
private fun convertFlavorToString(ing: Ingridient): String {
return when (ing) {
is Ingredients.Chocolate -> "Chocolate"
is Ingredients.Coconut -> "Coconut"
}
}
KOTLIN - DSL
SEALED CLASSES
sealed class Ingredients{
object Chocolate : Ingredients()
object Coconut : Ingredients()
object Sugar : Ingredients()
}
* when expression must be exhaustive
private fun convertFlavorToString(ing: Ingridient): String {
return when (ing) {
is Ingredients.Chocolate -> "Chocolate"
is Ingredients.Coconut -> "Coconut"
}
}
KOTLIN - DSL
SEALED CLASSES
sealed class Ingredients{
object Chocolate : Ingredients()
object Coconut : Ingredients()
object Sugar : Ingredients()
}
private fun convertFlavorToString(ing: Ingridient): String {
return when (ing) {
is Ingredients.Chocolate -> "Chocolate"
is Ingredients.Coconut -> "Coconut"
is Ingredients.Sugar -> "Sugar"
}
}
KOTLIN - DSL
SEALED CLASSES
sealed class Ingredients
object Chocolate : Ingredients()
object Coconut : Ingredients()
object Sugar : Ingredients()
private fun convertFlavorToString(ing: Ingridient): String {
return when (ing) {
is Ingredients.Chocolate -> "Chocolate"
is Ingredients.Coconut -> "Coconut"
is Ingredients.Sugar -> "Sugar"
}
}
KOTLIN - DSL
SEALED CLASSES
sealed class Ingredients
object Chocolate : Ingredients()
object Coconut : Ingredients()
object Sugar : Ingredients()
private fun convertFlavorToString(ing: Ingridient): String {
return when (ing) {
is Chocolate -> "Chocolate"
is Coconut -> "Coconut"
is Sugar -> "Sugar"
}
}
KOTLIN - DSL
SEALED CLASSES - SMART CASTING
sealed class VehicleState
object Empty : VehicleState()
data class Success(val vehicles: List<Vehile>) : VehicleState()
data class Error(error: Throwable) : VehicleState()
data class Loading(isLoading: Boolean) : VehicleState()
KOTLIN - DSL
SEALED CLASSES - SMART CASTING
sealed class VehicleState
object Empty : VehicleState()
data class Success(val vehicles: List<Vehile>) : VehicleState()
data class Error(error: Throwable) : VehicleState()
data class Loading(isLoading: Boolean) : VehicleState()
private fun updateState(state: VehicleState) {
when (state) {
is Empty -> ...
is Success -> state.vehicles
is Error -> state.error
is Loading -> state.isLoading
}
}
KOTLIN - DSL
SEALED
CLASS
Cooker
Cake
Chocolate
Coconut
Sugar
Birthday
make
of
and
withOut
forMy
INFIX
KOTLIN - DSL
CAKE
val cake = Cooker make Cake of Chocolate and Coconut withOut
Sugar forMy Birthday
print(cake)
UNIT
TEST
KOTLIN - DSL
UNIT TEST
data class User(val name:String, var balance: Double) {
fun withDraw(value: Double){
this.balance -= value
}
}
KOTLIN - DSL
UNIT TEST
//Given
val user = User("Roque", 200.0)
//When
user.withDraw(50.0)
//Then
Truth.assertThat(user.balance).isEqualTo(150.0)
KOTLIN - DSL
UNIT TEST
given {
User("Roque", 200.0)
}.test {
withDraw(50.0)
}.assert {
Truth.assertThat(balance).isEqualTo(150.0)
}
KOTLIN - DSL
UNIT TEST
fun <T, R> T.given(block: () -> R): R {
return block(this)
}
KOTLIN - DSL
UNIT TEST
fun <T> T.test(block: T.() -> Unit): T {
block()
return this
}
KOTLIN - DSL
UNIT TEST
fun <T> T.assert(block: T.() -> Unit) {
this.block()
}
KOTLIN - DSL
UNIT TEST
given {
User("Roque", 200.0)
}.test {
withDraw(50.0)
}.assert {
balance isEquals 150.0
}
KOTLIN - DSL
UNIT TEST
infix fun<T> T.isEquals(value: T):{
Truth.assertThat(this).isEqualTo(value)
}
KOTLIN - DSL
UNIT TEST
whenever(repository.increase()).thenReturn(Counter(1))
KOTLIN - DSL
UNIT TEST
whenever(repository.increase()).thenReturn(Counter(1))
repository.increase() willReturn Counter(1)
KOTLIN - DSL
UNIT TEST
whenever(repository.increase()).thenReturn(Counter(1))
repository.increase() willReturn Counter(1)
infix fun <T> T.willReturn(value: T) {
given(this)
.willReturn(value)
}
NEXT
STEPS?
KOTLIN - DSL
NEXT STEPS
▸Find your necessity
▸Check if already exist
▸Sync with your team
▸Be creative
▸Enjoy more readable code :)
KOTLIN - DSL
SUMMARIZE
▸Infix notation
▸Sealed Class
▸Higher order functions
▸Lambda with receivers
▸Lambda parameter
▸Operator overloading
THANK
YOU!!!
Q&
A’S

More Related Content

Similar to Kotlin dsl

JavaZone 2022 - Building Kotlin DSL.pdf
JavaZone 2022 - Building Kotlin DSL.pdfJavaZone 2022 - Building Kotlin DSL.pdf
JavaZone 2022 - Building Kotlin DSL.pdf
Anton Arhipov
 
ADG Poznań - Kotlin for Android developers
ADG Poznań - Kotlin for Android developersADG Poznań - Kotlin for Android developers
ADG Poznań - Kotlin for Android developers
Bartosz Kosarzycki
 
Kotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresKotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan Soares
iMasters
 
Building DSLs with Scala
Building DSLs with Scala Building DSLs with Scala
Building DSLs with Scala
Alon Muchnick
 
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017 Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Codemotion
 
Kotlin: forse è la volta buona (Trento)
Kotlin: forse è la volta buona (Trento)Kotlin: forse è la volta buona (Trento)
Kotlin: forse è la volta buona (Trento)
Davide Cerbo
 
Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016
Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016
Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016
STX Next
 
Kotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projectsKotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projects
Bartosz Kosarzycki
 
Joy of scala
Joy of scalaJoy of scala
Joy of scala
Maxim Novak
 
Kotlin: maybe it's the right time
Kotlin: maybe it's the right timeKotlin: maybe it's the right time
Kotlin: maybe it's the right time
Davide Cerbo
 
Getting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NETGetting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NET
Tomas Jansson
 
TechShift: There’s light beyond LAMP
TechShift: There’s light beyond LAMPTechShift: There’s light beyond LAMP
TechShift: There’s light beyond LAMP
Stephen Tallamy
 
Kotlin / Android Update
Kotlin / Android UpdateKotlin / Android Update
Kotlin / Android Update
Garth Gilmour
 
Kotlin decoration - February Berlin Kotlin Meetup
Kotlin decoration - February Berlin Kotlin MeetupKotlin decoration - February Berlin Kotlin Meetup
Kotlin decoration - February Berlin Kotlin Meetup
Sinan KOZAK
 
つくってあそぼ Kotlin DSL 第2版
つくってあそぼ Kotlin DSL 第2版つくってあそぼ Kotlin DSL 第2版
つくってあそぼ Kotlin DSL 第2版
kamedon39
 
Why Scala is the better Java
Why Scala is the better JavaWhy Scala is the better Java
Why Scala is the better Java
Thomas Kaiser
 
Introduction to type classes
Introduction to type classesIntroduction to type classes
Introduction to type classes
Pawel Szulc
 
«Продакшн в Kotlin DSL» Сергей Рыбалкин
«Продакшн в Kotlin DSL» Сергей Рыбалкин«Продакшн в Kotlin DSL» Сергей Рыбалкин
«Продакшн в Kotlin DSL» Сергей Рыбалкин
Mail.ru Group
 
Grailsでドメイン駆動設計を実践する時の勘所
Grailsでドメイン駆動設計を実践する時の勘所Grailsでドメイン駆動設計を実践する時の勘所
Grailsでドメイン駆動設計を実践する時の勘所
Takuma Watabiki
 
Scala4sling
Scala4slingScala4sling
Scala4sling
day
 

Similar to Kotlin dsl (20)

JavaZone 2022 - Building Kotlin DSL.pdf
JavaZone 2022 - Building Kotlin DSL.pdfJavaZone 2022 - Building Kotlin DSL.pdf
JavaZone 2022 - Building Kotlin DSL.pdf
 
ADG Poznań - Kotlin for Android developers
ADG Poznań - Kotlin for Android developersADG Poznań - Kotlin for Android developers
ADG Poznań - Kotlin for Android developers
 
Kotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresKotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan Soares
 
Building DSLs with Scala
Building DSLs with Scala Building DSLs with Scala
Building DSLs with Scala
 
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017 Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
 
Kotlin: forse è la volta buona (Trento)
Kotlin: forse è la volta buona (Trento)Kotlin: forse è la volta buona (Trento)
Kotlin: forse è la volta buona (Trento)
 
Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016
Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016
Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016
 
Kotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projectsKotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projects
 
Joy of scala
Joy of scalaJoy of scala
Joy of scala
 
Kotlin: maybe it's the right time
Kotlin: maybe it's the right timeKotlin: maybe it's the right time
Kotlin: maybe it's the right time
 
Getting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NETGetting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NET
 
TechShift: There’s light beyond LAMP
TechShift: There’s light beyond LAMPTechShift: There’s light beyond LAMP
TechShift: There’s light beyond LAMP
 
Kotlin / Android Update
Kotlin / Android UpdateKotlin / Android Update
Kotlin / Android Update
 
Kotlin decoration - February Berlin Kotlin Meetup
Kotlin decoration - February Berlin Kotlin MeetupKotlin decoration - February Berlin Kotlin Meetup
Kotlin decoration - February Berlin Kotlin Meetup
 
つくってあそぼ Kotlin DSL 第2版
つくってあそぼ Kotlin DSL 第2版つくってあそぼ Kotlin DSL 第2版
つくってあそぼ Kotlin DSL 第2版
 
Why Scala is the better Java
Why Scala is the better JavaWhy Scala is the better Java
Why Scala is the better Java
 
Introduction to type classes
Introduction to type classesIntroduction to type classes
Introduction to type classes
 
«Продакшн в Kotlin DSL» Сергей Рыбалкин
«Продакшн в Kotlin DSL» Сергей Рыбалкин«Продакшн в Kotlin DSL» Сергей Рыбалкин
«Продакшн в Kotlin DSL» Сергей Рыбалкин
 
Grailsでドメイン駆動設計を実践する時の勘所
Grailsでドメイン駆動設計を実践する時の勘所Grailsでドメイン駆動設計を実践する時の勘所
Grailsでドメイン駆動設計を実践する時の勘所
 
Scala4sling
Scala4slingScala4sling
Scala4sling
 

Recently uploaded

National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
Quotidiano Piemontese
 
Recommendation System using RAG Architecture
Recommendation System using RAG ArchitectureRecommendation System using RAG Architecture
Recommendation System using RAG Architecture
fredae14
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
Zilliz
 
Project Management Semester Long Project - Acuity
Project Management Semester Long Project - AcuityProject Management Semester Long Project - Acuity
Project Management Semester Long Project - Acuity
jpupo2018
 
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
saastr
 
UI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentationUI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentation
Wouter Lemaire
 
WeTestAthens: Postman's AI & Automation Techniques
WeTestAthens: Postman's AI & Automation TechniquesWeTestAthens: Postman's AI & Automation Techniques
WeTestAthens: Postman's AI & Automation Techniques
Postman
 
5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides
DanBrown980551
 
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial IntelligenceAI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
IndexBug
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
akankshawande
 
Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
tolgahangng
 
Ocean lotus Threat actors project by John Sitima 2024 (1).pptx
Ocean lotus Threat actors project by John Sitima 2024 (1).pptxOcean lotus Threat actors project by John Sitima 2024 (1).pptx
Ocean lotus Threat actors project by John Sitima 2024 (1).pptx
SitimaJohn
 
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with SlackLet's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
shyamraj55
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
Brandon Minnick, MBA
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
ssuserfac0301
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Tosin Akinosho
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
panagenda
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Safe Software
 
Webinar: Designing a schema for a Data Warehouse
Webinar: Designing a schema for a Data WarehouseWebinar: Designing a schema for a Data Warehouse
Webinar: Designing a schema for a Data Warehouse
Federico Razzoli
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
Matthew Sinclair
 

Recently uploaded (20)

National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
 
Recommendation System using RAG Architecture
Recommendation System using RAG ArchitectureRecommendation System using RAG Architecture
Recommendation System using RAG Architecture
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
 
Project Management Semester Long Project - Acuity
Project Management Semester Long Project - AcuityProject Management Semester Long Project - Acuity
Project Management Semester Long Project - Acuity
 
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
 
UI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentationUI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentation
 
WeTestAthens: Postman's AI & Automation Techniques
WeTestAthens: Postman's AI & Automation TechniquesWeTestAthens: Postman's AI & Automation Techniques
WeTestAthens: Postman's AI & Automation Techniques
 
5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides
 
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial IntelligenceAI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
 
Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
 
Ocean lotus Threat actors project by John Sitima 2024 (1).pptx
Ocean lotus Threat actors project by John Sitima 2024 (1).pptxOcean lotus Threat actors project by John Sitima 2024 (1).pptx
Ocean lotus Threat actors project by John Sitima 2024 (1).pptx
 
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with SlackLet's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
 
Webinar: Designing a schema for a Data Warehouse
Webinar: Designing a schema for a Data WarehouseWebinar: Designing a schema for a Data Warehouse
Webinar: Designing a schema for a Data Warehouse
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
 

Kotlin dsl

  • 2. About me :) ‣ Roque Buarque Junior ‣ Brazilian ‣ Android Engineer ‣ Berlin - Germany ‣ Sharenow ‣ @roqbjr
  • 3. KOTLIN - DSL WHAT YOU WILL SEE? ▸What is DSL? ▸DSL Examples ▸Kotlin features to build a DSL ▸Code ▸Code ▸And more CODE
  • 4. KOTLIN - DSL KOTLIN IN ACTION ▸Chapter 11 - DSL Construction
  • 5. A DOMAIN-SPECIFIC LANGUAGE (DSL) IS A COMPUTER LANGUAGE SPECIALIZED TO A PARTICULAR APPLICATION DOMAIN. THIS IS IN CONTRAST TO A GENERAL- PURPOSE LANGUAGE (GPL), WHICH IS BROADLY APPLICABLE ACROSS DOMAINS. From Wikipedia KOTLIN - DSL
  • 7. KOTLIN - DSL val list = mutableListOf("A", "B", "C").toList() val list = buildList { add("A") add("B") add("C") }
  • 8. KOTLIN - DSL HIGHER-ORDER FUNCTIONS AND LAMBDAS ▸Store in variables and data structures ▸Pass as argument to and return from other function A higher-order function is a function that takes functions as parameters, or returns a function.
  • 9. KOTLIN - DSL class Person { lateinit var name: String lateinit var email: String }
  • 10. KOTLIN - DSL class Person { lateinit var name: String lateinit var email: String } val person = Person() person.name = "Roque" person.email = "roque@email.com"
  • 12. KOTLIN - DSL class Person { lateinit var name: String lateinit var email: String } Person() .apply { this.name = "Roque" this.email = "roque@email.com" }
  • 13. KOTLIN - DSL class Person { lateinit var name: String lateinit var email: String } Person() .apply { name = "Roque" email = "roque@email.com" }
  • 14. KOTLIN - DSL val helloWorld = "Hello".apply { "$this World" } Hello
  • 15. KOTLIN - DSL Person() .apply { name = "Roque" email = "roque@email.com" } public inline fun <T> T.apply(block: T.() -> Unit): T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } block() return this }
  • 16. KOTLIN - DSL Person() .let { it.name = "Roque" it.email = "roque@email.com" }
  • 17. KOTLIN - DSL val helloWorld = "Hello".let { "$it World" } Hello World
  • 18. KOTLIN - DSL Person() .let { it.name = "Roque" it.email = "roque@email.com" } public inline fun <T, R> T.let(block: (T) -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return block(this) }
  • 19. KOTLIN - DSL fun helloWorld(block: () -> Unit) { println("Hello World") block() } helloWorld{ } Hello World
  • 20. KOTLIN - DSL fun helloWorld(block: (String) -> Unit) { println("Hello") block("World") } helloWorld{ print(it) } Hello World
  • 21. KOTLIN - DSL fun helloWorld(block: String.(String) -> Unit) { block(“Hello”, “World”) } helloWorld{ print(“$this $it”) } Hello World
  • 22. KOTLIN - DSL fun <T> T.helloWorld(block: T.() -> Unit) { block(this) } "Hello".helloWorld { print(this) } Hello
  • 23. KOTLIN - DSL fun <T, R> T.helloWorld(block: T.() -> R) : R { return block(this) } val helloWorld = "Hello".helloWorld { "$this World" } print(helloWorld) Hello World
  • 24. KOTLIN - DSL HTML <table> <tr> <td> cell </td> </tr> </table>
  • 25. KOTLIN - DSL HTML "<table> <tr> <td> cell </td> </tr> </table>"
  • 26. KOTLIN - DSL HTML “<table> <tr> <td> cell </td> </tr> </table>" createHTML(). table { tr { td { +”cell” } } } https://github.com/Kotlin/kotlinx.html
  • 27. KOTLIN - DSL SQL SELECT * FROM users WHERE age = 18
  • 28. KOTLIN - DSL SQL "SELECT * FROM users WHERE age = 18”
  • 29. KOTLIN - DSL EXPOSED - JETBRAINS https://github.com/JetBrains/Exposed/ "SELECT * FROM users WHERE age = 18” Users.select { Users.age eq 18 }
  • 30. KOTLIN - DSL SQL User select { age eq 18 }
  • 32. KOTLIN - DSL INFIX ▸Must be member function or extension function ▸Must have only a single parameter ▸The parameter must have no default value ▸The parameter must not accept varargs ▸Receiver and parameter must be specified Functions marked with the infix keyword can also be called using the infix notation(omitting the dot and the parentheses for the call)
  • 33. KOTLIN - DSL object User { operator fun invoke(query: String): User { this.query += query return this } infix fun select(block: User.() -> Unit) { User("SELECT * FROM users").block() } }
  • 34. KOTLIN - DSL object User { private var query = "" val age: User get() = this.where("age") val name: User get() = this.where("name") private fun where(field: String): User { query+= " WHERE $field" return this } infix fun eq(age: Int) { println("$query = $age") } }
  • 35. KOTLIN - DSL SQL User select { age eq 18 }
  • 36. KOTLIN - DSL SQL User select { age eq 18 } SELECT * FROM users WHERE age = 18
  • 38. KOTLIN - DSL CAKE val cake = Cooker make Cake of Chocolate and Coconut withOut Sugar forMy Birthday print(cake)
  • 40. KOTLIN - DSL INFIX class Cooker { fun make(value: Dish) { . . . } } Cooker().make(Cake())
  • 41. KOTLIN - DSL INFIX class Cooker { infix fun make(value: Dish) { . . . } } Cooker() make Cake()
  • 42. KOTLIN - DSL INFIX object Cooker { infix fun make(value: Dish) { . . . } } Cooker make Cake()
  • 44. KOTLIN - DSL SEALED CLASS ▸Is abstract by itself, cannot be instantiated ▸Not allowed to have non-private constructors (their constructors are private by default). Sealed classes are used for representing restricted class hierarchies, when a value can have one of the types from limited set, but cannot have any other type.
  • 45. KOTLIN - DSL SEALED CLASSES class Ingredients{ }
  • 46. KOTLIN - DSL SEALED CLASSES sealed class Ingredients{ }
  • 47. KOTLIN - DSL SEALED CLASSES sealed class Ingredients{ object Chocolate : Ingredients() object Coconut : Ingredients() object Sugar : Ingredients() }
  • 48. KOTLIN - DSL SEALED CLASSES sealed class Ingredients{ object Chocolate : Ingredients() object Coconut : Ingredients() object Sugar : Ingredients() } private fun convertFlavorToString(ing: Ingridient): String { return when (ing) { is Ingredients.Chocolate -> "Chocolate" is Ingredients.Coconut -> "Coconut" } }
  • 49. KOTLIN - DSL SEALED CLASSES sealed class Ingredients{ object Chocolate : Ingredients() object Coconut : Ingredients() object Sugar : Ingredients() } * when expression must be exhaustive private fun convertFlavorToString(ing: Ingridient): String { return when (ing) { is Ingredients.Chocolate -> "Chocolate" is Ingredients.Coconut -> "Coconut" } }
  • 50. KOTLIN - DSL SEALED CLASSES sealed class Ingredients{ object Chocolate : Ingredients() object Coconut : Ingredients() object Sugar : Ingredients() } private fun convertFlavorToString(ing: Ingridient): String { return when (ing) { is Ingredients.Chocolate -> "Chocolate" is Ingredients.Coconut -> "Coconut" is Ingredients.Sugar -> "Sugar" } }
  • 51. KOTLIN - DSL SEALED CLASSES sealed class Ingredients object Chocolate : Ingredients() object Coconut : Ingredients() object Sugar : Ingredients() private fun convertFlavorToString(ing: Ingridient): String { return when (ing) { is Ingredients.Chocolate -> "Chocolate" is Ingredients.Coconut -> "Coconut" is Ingredients.Sugar -> "Sugar" } }
  • 52. KOTLIN - DSL SEALED CLASSES sealed class Ingredients object Chocolate : Ingredients() object Coconut : Ingredients() object Sugar : Ingredients() private fun convertFlavorToString(ing: Ingridient): String { return when (ing) { is Chocolate -> "Chocolate" is Coconut -> "Coconut" is Sugar -> "Sugar" } }
  • 53. KOTLIN - DSL SEALED CLASSES - SMART CASTING sealed class VehicleState object Empty : VehicleState() data class Success(val vehicles: List<Vehile>) : VehicleState() data class Error(error: Throwable) : VehicleState() data class Loading(isLoading: Boolean) : VehicleState()
  • 54. KOTLIN - DSL SEALED CLASSES - SMART CASTING sealed class VehicleState object Empty : VehicleState() data class Success(val vehicles: List<Vehile>) : VehicleState() data class Error(error: Throwable) : VehicleState() data class Loading(isLoading: Boolean) : VehicleState() private fun updateState(state: VehicleState) { when (state) { is Empty -> ... is Success -> state.vehicles is Error -> state.error is Loading -> state.isLoading } }
  • 56. KOTLIN - DSL CAKE val cake = Cooker make Cake of Chocolate and Coconut withOut Sugar forMy Birthday print(cake)
  • 58. KOTLIN - DSL UNIT TEST data class User(val name:String, var balance: Double) { fun withDraw(value: Double){ this.balance -= value } }
  • 59. KOTLIN - DSL UNIT TEST //Given val user = User("Roque", 200.0) //When user.withDraw(50.0) //Then Truth.assertThat(user.balance).isEqualTo(150.0)
  • 60. KOTLIN - DSL UNIT TEST given { User("Roque", 200.0) }.test { withDraw(50.0) }.assert { Truth.assertThat(balance).isEqualTo(150.0) }
  • 61. KOTLIN - DSL UNIT TEST fun <T, R> T.given(block: () -> R): R { return block(this) }
  • 62. KOTLIN - DSL UNIT TEST fun <T> T.test(block: T.() -> Unit): T { block() return this }
  • 63. KOTLIN - DSL UNIT TEST fun <T> T.assert(block: T.() -> Unit) { this.block() }
  • 64. KOTLIN - DSL UNIT TEST given { User("Roque", 200.0) }.test { withDraw(50.0) }.assert { balance isEquals 150.0 }
  • 65. KOTLIN - DSL UNIT TEST infix fun<T> T.isEquals(value: T):{ Truth.assertThat(this).isEqualTo(value) }
  • 66. KOTLIN - DSL UNIT TEST whenever(repository.increase()).thenReturn(Counter(1))
  • 67. KOTLIN - DSL UNIT TEST whenever(repository.increase()).thenReturn(Counter(1)) repository.increase() willReturn Counter(1)
  • 68. KOTLIN - DSL UNIT TEST whenever(repository.increase()).thenReturn(Counter(1)) repository.increase() willReturn Counter(1) infix fun <T> T.willReturn(value: T) { given(this) .willReturn(value) }
  • 70. KOTLIN - DSL NEXT STEPS ▸Find your necessity ▸Check if already exist ▸Sync with your team ▸Be creative ▸Enjoy more readable code :)
  • 71. KOTLIN - DSL SUMMARIZE ▸Infix notation ▸Sealed Class ▸Higher order functions ▸Lambda with receivers ▸Lambda parameter ▸Operator overloading

Editor's Notes

  1. You will see a lot of code, if you are not that familiar with kotlin it might be like What is this, but I’m pretty sure you will learn something in general about DSL and be able to apply in your language/project.
  2. Content 2018 but there are still a lot of things to learn
  3. DSL is not only one feature from kotlin It’s actually not even a kotlin feature DSLs are languages which belongs for specific domains Bring to kotlin and the fancy way as possible
  4. Why should I know about DSL if I’m not using SQL or HTML or any other domain specific language in my code?
  5. Even kotlin is creating dsl from kotlin to kotlin Introduced in kotlin 1.3 Composable code Structure Functional programming Declarative Build list return list directly Huge reason to create DSL already
  6. Could be a date class but for the example fit better being just a class
  7. Java Not very kotlin What is the problem of this code? No context I can change the fields from anywhere Scope function
  8. Not when/where to use But how it works Dive deep into ti and see What scope function can TEACH us about high order functions.
  9. Lambda context High order function
  10. Omit my this Same that omit this activity
  11. If I print hellowWorld valuable, what will be the output of this? Kudos for who said Hello Do you know why do we have this output? Not concating? Not returning the last line? Why I have this inside the block? Lot of questions, right? Let’s dive deep to apply function and find more about it.
  12. Generic Extension function for any type High order function, receiving other function Adding my T as lambda receiver my context of my lambda Return the same type
  13. What will be the output of this?
  14. High order function
  15. High order function with lambda parameter
  16. High order function with lambda receiver and lambda parameter
  17. Extension function High order function With lambda receiver Without return
  18. 15 min Extension function High order function With lambda receiver With return
  19. Now the lib code seems not that weird for us High order function and receivers
  20. No structure, have type
  21. Bringing sql to kotlin domain Lib abstract Create my own, very poor but just to show two kotlin features.
  22. This will result in my sql string.
  23. If you follow you can use it
  24. Fake constructor initialising my query Infix Lambda receiver
  25. Could be better, but it’s just to show the infix and the operator overloading features
  26. User object What is select? Infix hight order function that contain lambda with receiver which is my user. Operator overloading to create fake constructor User to start my query Age concate my query and return my user Eq infix function contain int parameter and print my query
  27. 25 min Output
  28. Favorite Write in English
  29. Is possible to have chocolate without sugar? Not sure Is possible to write English with kotlin? YES
  30. Not English yet
  31. Not close yet
  32. Almost there If I make my cake object then it’s done Dish parameter
  33. You can’t extend in other file
  34. Show the parent
  35. Remove the braces
  36. Not SN code
  37. Access to the fields
  38. Only two features helped me to create my cake DSL
  39. 32 min And write in English inside kotlin domain
  40. Cake was funny but yeah, not very useful Readability
  41. Test withDraw
  42. The standard
  43. Structure
  44. Extension function High order function Return last line
  45. Extension function High order function Return same type
  46. Extension function High order function Without return
  47. What about I could extract the truth lib?
  48. If I want to change my assert library, I have only few places and not in all my unit tests
  49. Verbose
  50. Readability
  51. Method call will return
  52. 40min How create is done When to create a DSL? Easy WillThrow or others Be creative