SlideShare ist ein Scribd-Unternehmen logo
1 von 28
Downloaden Sie, um offline zu lesen
Domain Specific Languages in Kotlin
Theory and Practice
Stefan Scheidt, REWE digital
Domain Specific Languages
A domain-specific language (DSL) is a computer language specialized
to a particular application domain.
— Wikipedia
Examples
• HTML
• SQL
• Regular Expressions
• ...
Embedded DSLs
Embedded (or internal) domain-specific languages are implemented as
libraries which exploit the syntax of their host general purpose
language
— Wikipedia
Kotlin DSLs
A domain-specific language embedded in Kotlin
Examples - HTML 1
System.out.appendHTML().html {
body {
div {
a("http://kotlinlang.org") {
target = ATarget.blank
+"Main site"
}
}
}
}
1 
kotlinx.html, https://github.com/Kotlin/kotlinx.html
Examples - JSON 2
import com.github.salomonbrys.kotson.*
val obj: JsonObject = jsonObject(
"property" to "value",
"array" to jsonArray(
21,
"fourty-two",
jsonObject("go" to "hell")
)
)
2 
Kotson, https://github.com/SalomonBrys/Kotson
Examples - Gradle 3
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm") version "1.2.60"
}
repositories {
mavenCentral()
}
dependencies {
compile(kotlin("stdlib-jdk8"))
}
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
}
3 
Kotlin Gradle DSL, https://github.com/gradle/kotlin-dsl
Examples - Android Layouts 4
verticalLayout {
val name = editText {
hint = "Name"
textSize = 24f
}
button("Say Hello") {
onClick {
toast("Hello, ${name.text}!")
}
}
}
4 
Kotlin Anko Layouts, https://github.com/Kotlin/anko/wiki/Anko-Layouts
Build your own DSL
Ingredients
Extention functions
Instead of this
fun <T> swap(list: MutableList<T>, index1: Int, index2: Int) {
val tmp = list[index1]
list[index1] = list[index2]
list[index2] = tmp
}
val list = mutableListOf(1, 2, 3)
swap(list, 1, 2)
Extention functions
... we can write this
fun <T> MutableList<T>.swap(index1: Int, index2: Int) {
val tmp = this[index1] // 'this' corresponds to the list
this[index1] = this[index2]
this[index2] = tmp
}
val list = mutableListOf(1, 2, 3)
list.swap(1,2)
Lambda Expressions with Receivers
So what does this do?
val printMe: String.() -> Unit = { println(this) }
"Stefan".printMe()
Lambda Expressions with Receivers
Now let's assume we have a class
class HTML {
fun head() {}
fun body() {}
}
and a function
fun html(init: HTML.() -> Unit): HTML {
val html = HTML()
html.init()
return html
}
Lambda Expressions with Receivers
... then we can write
html({
head()
body()
})
Lambda Expressions with Receivers
We apply syntactic sugger:
html() {
head()
body()
}
Lambda Expressions with Receivers
And again:
html {
head()
body()
}
Lambda Expressions with Receivers
Now let's go from here
class HTML {
fun head() {}
fun body() {}
}
Lambda Expressions with Receivers
... to here:
class HTML {
fun head(init: Head.() -> Unit): Head {
val head = Head(); head.init(); return head
}
fun body(init: Body.() -> Unit): Body {
val body = Body(); body.init(); return body
}
}
class Head { fun title() { } }
class Body { fun p() { } }
Lambda Expressions with Receivers
Then we can write
html {
head {
title()
}
body {
p()
}
}
... and so on.
Scope control
But ...
html {
head {
head {
title()
}
}
// ...
}
will also be OK. :-(
DSL Markers
Control receiver scope with @DslMarker:
@DslMarker
annotation class HtmlTagMarker
@HtmlTagMarker
class HTML { // ...
}
@HtmlTagMarker
class Head { // ...
}
@HtmlTagMarker
class Body { // ...
}
DSL Markers
Now we will get
$ ./gradlew compileKotlin
e: .../html.kt: (32, 13): 'fun head(init: Head.() -> Unit):
Head' can't be called in this context by implicit receiver.
Use the explicit one if necessary
> Task :compileKotlin FAILED
DSL Markers
Well, we still could write
html {
head {
this@html.head {
title()
}
}
// ...
}
The whole example could be found here: Type-Safe builders.
Invoke
With
class MyClass {
operator fun invoke() { // ...
}
}
one can write
val myObj = MyClass()
myObj() // will call invoke
Invoke for DSLs
With
class Family {
operator fun invoke(body: Family.() -> Unit) { body() }
fun addMember(name: String) {}
}
one can write
val family = Family()
family {
addMember("Mom"); addMember("Dad"); addMember("Kid")
}
More Examples for DSLs
• https://dzone.com/articles/kotlin-dsl-from-theory-to-practice
convert Test Data Builder to Kotlin DSL
• https://kotlinexpertise.com/java-builders-kotlin-dsls/
convert Java builders for Android Material Drawer to Kotlin DSL
• https://blog.codecentric.de/2018/06/kotlin-dsl-apache-kafka/
A simple example of Kotlin DSL for Apache Kafka producer and
consumer (German)
Thank you!
@stefanscheidt on Twitter and GitHub
This presentation can be found here

Weitere ähnliche Inhalte

Was ist angesagt?

Was ist angesagt? (19)

Iron python
Iron pythonIron python
Iron python
 
Kotlin
KotlinKotlin
Kotlin
 
Redesigning Common Lisp
Redesigning Common LispRedesigning Common Lisp
Redesigning Common Lisp
 
Open Source Compiler Construction for the JVM [LCA2011 Miniconf]
Open Source Compiler Construction for the JVM [LCA2011 Miniconf]Open Source Compiler Construction for the JVM [LCA2011 Miniconf]
Open Source Compiler Construction for the JVM [LCA2011 Miniconf]
 
effective_r27
effective_r27effective_r27
effective_r27
 
Java/Scala Lab: Руслан Шевченко - Implementation of CSP (Communication Sequen...
Java/Scala Lab: Руслан Шевченко - Implementation of CSP (Communication Sequen...Java/Scala Lab: Руслан Шевченко - Implementation of CSP (Communication Sequen...
Java/Scala Lab: Руслан Шевченко - Implementation of CSP (Communication Sequen...
 
Ekon 25 Python4Delphi_MX475
Ekon 25 Python4Delphi_MX475Ekon 25 Python4Delphi_MX475
Ekon 25 Python4Delphi_MX475
 
Introduction to Scalding and Monoids
Introduction to Scalding and MonoidsIntroduction to Scalding and Monoids
Introduction to Scalding and Monoids
 
Arduino C maXbox web of things slide show
Arduino C maXbox web of things slide showArduino C maXbox web of things slide show
Arduino C maXbox web of things slide show
 
Runtime Bytecode Transformation for Smalltalk
Runtime Bytecode Transformation for SmalltalkRuntime Bytecode Transformation for Smalltalk
Runtime Bytecode Transformation for Smalltalk
 
LCDS - State Presentation
LCDS - State PresentationLCDS - State Presentation
LCDS - State Presentation
 
EKON 25 Python4Delphi_mX4
EKON 25 Python4Delphi_mX4EKON 25 Python4Delphi_mX4
EKON 25 Python4Delphi_mX4
 
DConf 2016: Bitpacking Like a Madman by Amaury Sechet
DConf 2016: Bitpacking Like a Madman by Amaury SechetDConf 2016: Bitpacking Like a Madman by Amaury Sechet
DConf 2016: Bitpacking Like a Madman by Amaury Sechet
 
maXbox Starter 39 GEO Maps Tutorial
maXbox Starter 39 GEO Maps TutorialmaXbox Starter 39 GEO Maps Tutorial
maXbox Starter 39 GEO Maps Tutorial
 
Performance .NET Core - M. Terech, P. Janowski
Performance .NET Core - M. Terech, P. JanowskiPerformance .NET Core - M. Terech, P. Janowski
Performance .NET Core - M. Terech, P. Janowski
 
Algebird : Abstract Algebra for big data analytics. Devoxx 2014
Algebird : Abstract Algebra for big data analytics. Devoxx 2014Algebird : Abstract Algebra for big data analytics. Devoxx 2014
Algebird : Abstract Algebra for big data analytics. Devoxx 2014
 
05 pig user defined functions (udfs)
05 pig user defined functions (udfs)05 pig user defined functions (udfs)
05 pig user defined functions (udfs)
 
A closure ekon16
A closure ekon16A closure ekon16
A closure ekon16
 
Metrics ekon 14_2_kleiner
Metrics ekon 14_2_kleinerMetrics ekon 14_2_kleiner
Metrics ekon 14_2_kleiner
 

Ähnlich wie Kotlin DSLs

Scala4sling
Scala4slingScala4sling
Scala4sling
day
 
Smoothing Your Java with DSLs
Smoothing Your Java with DSLsSmoothing Your Java with DSLs
Smoothing Your Java with DSLs
intelliyole
 
Java script
 Java script Java script
Java script
bosybosy
 
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
lennartkats
 
Creating A Language Editor Using Dltk
Creating A Language Editor Using DltkCreating A Language Editor Using Dltk
Creating A Language Editor Using Dltk
Kaniska Mandal
 

Ähnlich wie Kotlin DSLs (20)

C++ Boot Camp Part 2
C++ Boot Camp Part 2C++ Boot Camp Part 2
C++ Boot Camp Part 2
 
Kotlin boost yourproductivity
Kotlin boost yourproductivityKotlin boost yourproductivity
Kotlin boost yourproductivity
 
Scala4sling
Scala4slingScala4sling
Scala4sling
 
Smoothing Your Java with DSLs
Smoothing Your Java with DSLsSmoothing Your Java with DSLs
Smoothing Your Java with DSLs
 
Coding for Android on steroids with Kotlin
Coding for Android on steroids with KotlinCoding for Android on steroids with Kotlin
Coding for Android on steroids with Kotlin
 
Building a Tagless Final DSL for WebGL
Building a Tagless Final DSL for WebGLBuilding a Tagless Final DSL for WebGL
Building a Tagless Final DSL for WebGL
 
Introduction to kotlin
Introduction to kotlinIntroduction to kotlin
Introduction to kotlin
 
Java script
 Java script Java script
Java script
 
Power tools in Java
Power tools in JavaPower tools in Java
Power tools in Java
 
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
 
Scoobi - Scala for Startups
Scoobi - Scala for StartupsScoobi - Scala for Startups
Scoobi - Scala for Startups
 
Tml for Objective C
Tml for Objective CTml for Objective C
Tml for Objective C
 
Creating A Language Editor Using Dltk
Creating A Language Editor Using DltkCreating A Language Editor Using Dltk
Creating A Language Editor Using Dltk
 
A New Chapter of Data Processing with CDK
A New Chapter of Data Processing with CDKA New Chapter of Data Processing with CDK
A New Chapter of Data Processing with CDK
 
Return of c++
Return of c++Return of c++
Return of c++
 
The Style of C++ 11
The Style of C++ 11The Style of C++ 11
The Style of C++ 11
 
Xtext Webinar
Xtext WebinarXtext Webinar
Xtext Webinar
 
Kotlin- Basic to Advance
Kotlin- Basic to Advance Kotlin- Basic to Advance
Kotlin- Basic to Advance
 
Design patterns with kotlin
Design patterns with kotlinDesign patterns with kotlin
Design patterns with kotlin
 
Cs267 hadoop programming
Cs267 hadoop programmingCs267 hadoop programming
Cs267 hadoop programming
 

Mehr von Stefan Scheidt

ipdc10: Spring Backends für iOS Apps
ipdc10: Spring Backends für iOS Appsipdc10: Spring Backends für iOS Apps
ipdc10: Spring Backends für iOS Apps
Stefan Scheidt
 
WJAX 2010: Spring Backends für iOS Apps
WJAX 2010: Spring Backends für iOS AppsWJAX 2010: Spring Backends für iOS Apps
WJAX 2010: Spring Backends für iOS Apps
Stefan Scheidt
 

Mehr von Stefan Scheidt (10)

Understanding the Four Rules of Simple Design
Understanding the Four Rules of Simple DesignUnderstanding the Four Rules of Simple Design
Understanding the Four Rules of Simple Design
 
iOS Einstieg und Ausblick
iOS Einstieg und AusblickiOS Einstieg und Ausblick
iOS Einstieg und Ausblick
 
iOS: Einstieg und Ausblick
iOS: Einstieg und AusblickiOS: Einstieg und Ausblick
iOS: Einstieg und Ausblick
 
Java script data binding mit jQuery Mobile
Java script data binding mit jQuery MobileJava script data binding mit jQuery Mobile
Java script data binding mit jQuery Mobile
 
Test driven java script development
Test driven java script developmentTest driven java script development
Test driven java script development
 
Fruehling fuers iPhone
Fruehling fuers iPhoneFruehling fuers iPhone
Fruehling fuers iPhone
 
Maven 3 New Features
Maven 3 New FeaturesMaven 3 New Features
Maven 3 New Features
 
Automatischer Build mit Maven
Automatischer Build mit MavenAutomatischer Build mit Maven
Automatischer Build mit Maven
 
ipdc10: Spring Backends für iOS Apps
ipdc10: Spring Backends für iOS Appsipdc10: Spring Backends für iOS Apps
ipdc10: Spring Backends für iOS Apps
 
WJAX 2010: Spring Backends für iOS Apps
WJAX 2010: Spring Backends für iOS AppsWJAX 2010: Spring Backends für iOS Apps
WJAX 2010: Spring Backends für iOS Apps
 

Kürzlich hochgeladen

Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
chiefasafspells
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
masabamasaba
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
masabamasaba
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
masabamasaba
 

Kürzlich hochgeladen (20)

Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security Program
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - Keynote
 

Kotlin DSLs

  • 1. Domain Specific Languages in Kotlin Theory and Practice Stefan Scheidt, REWE digital
  • 2. Domain Specific Languages A domain-specific language (DSL) is a computer language specialized to a particular application domain. — Wikipedia
  • 3. Examples • HTML • SQL • Regular Expressions • ...
  • 4. Embedded DSLs Embedded (or internal) domain-specific languages are implemented as libraries which exploit the syntax of their host general purpose language — Wikipedia
  • 5. Kotlin DSLs A domain-specific language embedded in Kotlin
  • 6. Examples - HTML 1 System.out.appendHTML().html { body { div { a("http://kotlinlang.org") { target = ATarget.blank +"Main site" } } } } 1  kotlinx.html, https://github.com/Kotlin/kotlinx.html
  • 7. Examples - JSON 2 import com.github.salomonbrys.kotson.* val obj: JsonObject = jsonObject( "property" to "value", "array" to jsonArray( 21, "fourty-two", jsonObject("go" to "hell") ) ) 2  Kotson, https://github.com/SalomonBrys/Kotson
  • 8. Examples - Gradle 3 import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { kotlin("jvm") version "1.2.60" } repositories { mavenCentral() } dependencies { compile(kotlin("stdlib-jdk8")) } tasks.withType<KotlinCompile> { kotlinOptions.jvmTarget = "1.8" } 3  Kotlin Gradle DSL, https://github.com/gradle/kotlin-dsl
  • 9. Examples - Android Layouts 4 verticalLayout { val name = editText { hint = "Name" textSize = 24f } button("Say Hello") { onClick { toast("Hello, ${name.text}!") } } } 4  Kotlin Anko Layouts, https://github.com/Kotlin/anko/wiki/Anko-Layouts
  • 10. Build your own DSL Ingredients
  • 11. Extention functions Instead of this fun <T> swap(list: MutableList<T>, index1: Int, index2: Int) { val tmp = list[index1] list[index1] = list[index2] list[index2] = tmp } val list = mutableListOf(1, 2, 3) swap(list, 1, 2)
  • 12. Extention functions ... we can write this fun <T> MutableList<T>.swap(index1: Int, index2: Int) { val tmp = this[index1] // 'this' corresponds to the list this[index1] = this[index2] this[index2] = tmp } val list = mutableListOf(1, 2, 3) list.swap(1,2)
  • 13. Lambda Expressions with Receivers So what does this do? val printMe: String.() -> Unit = { println(this) } "Stefan".printMe()
  • 14. Lambda Expressions with Receivers Now let's assume we have a class class HTML { fun head() {} fun body() {} } and a function fun html(init: HTML.() -> Unit): HTML { val html = HTML() html.init() return html }
  • 15. Lambda Expressions with Receivers ... then we can write html({ head() body() })
  • 16. Lambda Expressions with Receivers We apply syntactic sugger: html() { head() body() }
  • 17. Lambda Expressions with Receivers And again: html { head() body() }
  • 18. Lambda Expressions with Receivers Now let's go from here class HTML { fun head() {} fun body() {} }
  • 19. Lambda Expressions with Receivers ... to here: class HTML { fun head(init: Head.() -> Unit): Head { val head = Head(); head.init(); return head } fun body(init: Body.() -> Unit): Body { val body = Body(); body.init(); return body } } class Head { fun title() { } } class Body { fun p() { } }
  • 20. Lambda Expressions with Receivers Then we can write html { head { title() } body { p() } } ... and so on.
  • 21. Scope control But ... html { head { head { title() } } // ... } will also be OK. :-(
  • 22. DSL Markers Control receiver scope with @DslMarker: @DslMarker annotation class HtmlTagMarker @HtmlTagMarker class HTML { // ... } @HtmlTagMarker class Head { // ... } @HtmlTagMarker class Body { // ... }
  • 23. DSL Markers Now we will get $ ./gradlew compileKotlin e: .../html.kt: (32, 13): 'fun head(init: Head.() -> Unit): Head' can't be called in this context by implicit receiver. Use the explicit one if necessary > Task :compileKotlin FAILED
  • 24. DSL Markers Well, we still could write html { head { this@html.head { title() } } // ... } The whole example could be found here: Type-Safe builders.
  • 25. Invoke With class MyClass { operator fun invoke() { // ... } } one can write val myObj = MyClass() myObj() // will call invoke
  • 26. Invoke for DSLs With class Family { operator fun invoke(body: Family.() -> Unit) { body() } fun addMember(name: String) {} } one can write val family = Family() family { addMember("Mom"); addMember("Dad"); addMember("Kid") }
  • 27. More Examples for DSLs • https://dzone.com/articles/kotlin-dsl-from-theory-to-practice convert Test Data Builder to Kotlin DSL • https://kotlinexpertise.com/java-builders-kotlin-dsls/ convert Java builders for Android Material Drawer to Kotlin DSL • https://blog.codecentric.de/2018/06/kotlin-dsl-apache-kafka/ A simple example of Kotlin DSL for Apache Kafka producer and consumer (German)
  • 28. Thank you! @stefanscheidt on Twitter and GitHub This presentation can be found here