A domain-specific language (DSL) expresses operations in one focused problem domain while leaving out general-purpose capabilities that domain does not need. SQL and regular expressions are familiar standalone DSLs: each uses compact, task-specific syntax rather than providing everything needed to build an application. DSLs are often declarative, describing a desired result while an execution engine handles the details. section 13.1.1
A Kotlin DSL is an internal language: ordinary Kotlin constructs are arranged to read like a specialized notation. It can make configuration, object construction, database access, HTML generation, tests, and build scripts more direct without losing static typing, compile-time error detection, or IDE support. section 13.0 section 13.1
Routing with a Kotlin DSL
Ktor uses nested blocks to declare HTTP routing: embeddedServer(Netty, port = 8000) { routing { get("/world") { call.respondText("Hello, world!") } route("/greet") { get { /* ... */ } post("/{entityId}") { /* ... */ } } } } routing, get, post, and route look like language keywords, but they are framework-defined Kotlin constructs. The nesting groups related routes and carries routing context into each block, replacing annotation- or XML-based configuration. section 1.3.1
The boundary between a DSL and a clean API is not rigid. A regular command-query API typically calls methods independently; a DSL adds grammar, so several calls form one meaningful operation. Kotlin commonly creates that structure with lambdas with receivers, chained calls, infix calls, operator conventions, and builder functions. The type checker constrains which pieces can be combined. section 13.1 section 13.1.3
dependencies { #1
testImplementation(kotlin("test"))
implementation("org.jetbrains.exposed:exposed-core:0.40.1")
implementation("org.jetbrains.exposed:exposed-dao:0.40.1")
}
The dependencies block shows grammar and shared context: dependency declarations stay inside dependencies instead of repeatedly naming project.dependencies. This reduces repetition compared with a command-query API while retaining typed Kotlin calls. section 13.1.3
Readable test assertions
An infix DSL can turn a conventional assertion into a sentence-like expression: s should startWith("K") Here, should is an infix extension function and startWith produces a matcher. The notation reduces punctuation, but an invalid combination still fails at compile time because the DSL remains statically typed. section 13.4.1









