Domain Specific Language in Kotlin: Difference between revisions
Line 62: | Line 62: | ||
it.append("MyAttribute") | it.append("MyAttribute") | ||
} | } | ||
print(xml) | print(xml) | ||
</syntaxhighlight> | </syntaxhighlight> |
Revision as of 00:33, 13 April 2021
Introduction
Approaches to Extending Code
There may three options for extending a feature
- Change the Object Model
This has imperative code and therefore you will be forced to abstract extend, abstract extend. You be able to build quickly but it does not scale.
- External DSL (e.g. JSON)
E.g. Use json to describe the new features. You will need to extend the parser and write the code. Build will be slow but the scalability will be great
- DSL in Kotlin
Because it is just kotlin building will be quicker and it will scale hmmmmmm
Attributes of DSL Code
- Language Nature Code is meaningful and has a fluid nature
- Domain Focus DSL is focus one problem only
- Limited Expressiveness Supports only what it needs to to accomplished its task
Imperative vs Declarative
val castle = Castle()
val towerNE = Tower()
val towerSE = Tower()
val towerNW = Tower()
val towerSW = Tower()
val keep = Keep()
keep.connectTo(towerNE)
keep.connectTo(towerSE)
keep.connectTo(towerNW)
keep.connectTo(towerSW)
DSL Restricts the syntax to allow better IDE support and keep focus
castle {
keep {
to("sw")
to("nw")
to("se")
to("nw")
}
}
val castle = Castle()
val towerNE = Tower()
val towerSE = Tower()
Kotlin Language Features
Lambda with Receiver Invoke
A lambda with a receiver allows you to call methods of an object in the body of a lambda without any qualifiers. It is similar to the typed extension function but this time, for function types. The idea is similar to object initializers in C# but is extended to functions and in a declarative way.
We pass an object (StringBuilder) with an attibute (String) and a function to use with the two.
fun encloseInXMLAttribute(
sb : StringBuilder,
attr : String, action :
(StringBuilder) -> Unit) : String {
sb.append("<$attr>")
action(sb)
sb.append("</$attr>")
return sb.toString()
}
// When a lambda expression is at the end of the parameter list, you can take it out of the parentheses during invocation.
val xml = encloseInXMLAttribute(StringBuilder(), "attr") {
it.append("MyAttribute")
}
print(xml)