Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.

GeeCON Prague 2018 - Kotlin DSL in under an hour

161 visualizaciones

Publicado el

How to create your own DSL in Kotlin:
- Extension methods
- Extension properties
- Lamdas
- Lambda with receiver
- Infix functions
- Syntactic sugar

Publicado en: Tecnología
  • Sé el primero en comentar

  • Sé el primero en recomendar esto

GeeCON Prague 2018 - Kotlin DSL in under an hour

  1. 1. Kotlin DSL
 in under an hour @antonarhipov Prague, 18-19 October 2018
  2. 2. DSLanother Yet talk
  3. 3. DSL wat??
  4. 4. External DSL
  5. 5. Internal DSL
  6. 6. createHTML().html { head { +"Hello!" } body { ul { p { +"This is my awesome text!" } } } } kotlinx.html https://github.com/Kotlin/kotlinx.html
  7. 7. Anko https://github.com/Kotlin/anko verticalLayout { padding = dip(30) val name = editText { hint = "Name" textSize = 24f } val pwd = editText { hint = "Password" textSize = 24f button("Login") { textSize = 26f onClick { toast("Hello, ${name.text}!") } }
  8. 8. Gradle Kotlin DSL https://github.com/gradle/kotlin-dsl plugins { java kotlin("jvm") version "1.2.70" } group = "org.arhan" version = "1.0-SNAPSHOT" repositories { maven { setUrl("http://dl.bintray.com/kotlin/kotlin-eap") } jcenter() } dependencies { val kotlinx_html_version = "0.6.11" compile(kotlin("stdlib-jdk8")) compile("org.jetbrains.kotlinx:kotlinx-html-jvm:${kotlinx_html_version}") testCompile("junit", "junit", "4.12")
  9. 9. Exposed https://github.com/JetBrains/Exposed object Cities : Table() { val id = integer("id").autoIncrement().primaryKey() // Column<Int> val name = varchar("name", 50) // Column<String> } transaction { create (Cities) val tallinnId = Cities.insert { it[name] = "Tallinn" } get Cities.id for (city in Cities.selectAll()) { println("${city[Cities.id]}: ${city[Cities.name]}") } }
  10. 10. https://github.com/nfrankel/kaadin Kaadin theme = "valo" verticalLayout(margin = true, spacing = true) { tabSheet { tab("Interactions") { accordion { tab("Button", HAND_O_RIGHT) { horizontalLayout(true, true) { button() button("Label") button("Label", HAND_O_RIGHT) button("Click me", onClick = { show("Clicked") }) button("Click me", HAND_O_RIGHT, { show("Clicked") }) } }
  11. 11. k8s-kotlin-dsl https://github.com/fkorotkov/k8s-kotlin-dsl val client = DefaultKubernetesClient().inNamespace("default") client.extensions().ingresses().createOrReplace( newIngress { metadata { name = "example-ingress" } spec { backend { serviceName = "example-service" servicePort = IntOrString(8080) } } } )
  12. 12. Kotlin DSL in TeamCity project { vcsRoot(ApplicationVcs) buildType { id("Application") name = "Application" vcs { root(ApplicationVcs) } artifactRules = "target/*jar" steps { maven { goals = "clean package" } } triggers { vcs {} } dependencies { snapshot(Library) {}
  13. 13. fun main(args: Array<String>) { embeddedServer(Jetty, commandLineEnvironment(args)).start(wait = true) } fun Application.main() { install(DefaultHeaders) install(CallLogging) routing { get("/") { call.respondHtml { head { title { +"Ktor App" } } body { p { +"Hello from Ktor!" } } Ktor
  14. 14. They all look similar
  15. 15. foo { bar { baz = "Hello!" qux = quux { corge = "Blah" } } }
  16. 16. foo { bar { baz = "Hello!" qux = quux { corge = "Blah" } } }
  17. 17. foo { bar { baz = "Hello!" qux = quux { corge = "Blah" } } }
  18. 18. foo { bar { baz = "Hello!" qux = quux { corge = "Blah" } } }
  19. 19. foo { bar(grault = 1) { baz = "Hello!" qux = quux { corge = "Blah" } } }
  20. 20. foo { bar(grault = 1) { baz = "Hello!" qux = quux { corge = Blah() } } }
  21. 21. foo { bar(grault = 1) { baz = "Hello!" qux = quux { corge = Blah() } } }
  22. 22. Let’s write some code! https://github.com/jonnyzzz/kotlin-dsl-demo
  23. 23. Type-safe builders https://kotlinlang.org/docs/reference/type-safe-builders.html
  24. 24. final ClientBuilder builder = new ClientBuilder(); builder.setFirstName("Anton"); builder.setLastName("Arhipov"); final TwitterBuilder twitterBuilder = new TwitterBuilder(); twitterBuilder.setHandle("@antonarhipov"); builder.setTwitter(twitterBuilder.build()); final CompanyBuilder companyBuilder = new CompanyBuilder(); companyBuilder.setName("JetBrains"); companyBuilder.setCity("Tallinn"); builder.setCompany(companyBuilder.build()); final Client client = builder.build(); System.out.println("Created client is: " + client); val client = createClient { firstName = "Anton" lastName = "Arhipov" twitter { handle = "@antonarhipov" } company { name = "JetBrains" city = "Tallinn" } } println("Created client is: " + client.consoleString)
  25. 25. //extension property val Client.consoleString: String get() = "${twitter.handle} ${company.name}" //extension method fun Client.toConsoleString(): String { return "${twitter.handle} ${company.name}" }
  26. 26. fun createClient(c: ClientBuilder.() -> Unit): Client { val builder = ClientBuilder() c(builder) return builder.build() } fun ClientBuilder.company(t: CompanyBuilder.() -> Unit) { company = CompanyBuilder().apply(t).build() } fun ClientBuilder.twitter(t: CompanyBuilder.() -> Unit) { twitter = TwitterBuilder().apply(t).build() } Lambda with receiver Extension methods
  27. 27. twitter { handle = "@antonarhipov" company { name = "JetBrains" city = "Tallinn" } } @DslMarker annotation class ClientDsl @ClientDsl class CompanyBuilderDsl : CompanyBuilder() @ClientDsl class TwitterBuilderDsl : TwitterBuilder() twitter { handle = "@antonarhipov" company { name = "JetBrains" city = "Tallinn" } } Scope control
  28. 28. Infix notation https://kotlinlang.org/docs/reference/functions.html
  29. 29. dateTime = LocalDateTime.of(2018, Month.DECEMBER, 11, 0, 0) dateTime = 11 December 2018 at (14 hh 0) infix fun Int.December(n: Int) : LocalDate { return LocalDate.of(n, Month.DECEMBER, this) } infix fun LocalDate.at(n: Pair<Int, Int>): LocalDateTime { return this.atTime(n.first, n.second) } infix fun Int.hh(n: Int): Pair<Int, Int> { return Pair(this, n) }
  30. 30. T.() -> Unit
  31. 31. me { name = "Anton Arhipov" twitter = "@antonarhipov" } books { courses { Kotlin { Try = "try.kotlinlang.org" Slack = "slack.kotl.in" }

×