CodeBlanks Logo Icon CodeBlanks

Summary - Compile-time safety

Combine contracts, inline and type-safe builders to write a DSL.

Summary - Compile-time safety

In this group you learned five compile-time safety tools: contracts, inline, reified, tailrec and @DslMarker.

contracts commits behaviour to the compiler; inline cuts lambda overhead; reified bypasses type erasure; tailrec turns recursion into a loop; @DslMarker blocks receiver mixing in DSLs. Now you will write a small DSL that combines them: a box that reads its value's type via reified and avoids overhead with inline.

Combining: Box DSL

Now we will write a Box DSL that combines inline + reified + @DslMarker. A Box holds a value; it reads the type tag via reified.

Example: @BoxDsl class Box<T>(var value: T). inline fun <reified T> tag(): String = T::class.simpleName ?: "?". Box gets fun describe(): String = "${tag<T>()}:$value". But tag<T>() inside Box must be in an inline function, because T is only visible with inline/reified. So describe must be inline too.

Practice Write the Box DSL

Define @DslMarker annotation class BoxDsl. Write inline fun <reified T> tag(): String = T::class.simpleName ?: "?". Inside @BoxDsl class Box<T>(var value: T) add inline fun describe(): String = "${'$'}{tag<T>()}:${'$'}value". In main, write val b = Box(42) and println(b.describe()).

Starter code

Main.kt
// Write the Box DSL

annotation class BoxDsl

// add the tag function

class Box<T>(var value: T) {
    // add the describe method
}

fun main() {
    val b = Box(42)
    // print the describe output
}

Sample solution

Main.kt
@DslMarker
annotation class BoxDsl
inline fun <reified T> tag(): String = T::class.simpleName ?: "?"
@BoxDsl
class Box<T>(var value: T) {
    inline fun describe(): String = "${tag<T>()}:$value"
}
fun main() {
    val b = Box(42)
    println(b.describe())
}

Expected output

Int:42

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Which keyword cuts lambda overhead?

  • inline Correct answer
  • reified
  • tailrec
  • @DslMarker

Explanation: inline copies the body to the call site for lambda-parameter functions.

2 Complete the describe method

Question
    inline fun describe(): String = "${____<T>()}:$value"
Answer
    inline fun describe(): String = "${tag<T>()}:$value"

Explanation: tag<T>() returns the type name via reified.

3 Match the five tools

Term Meaning
contracts Behaviour commitment
inline Copies the body
reified Bypasses erasure
tailrec Turns into a loop
@DslMarker Blocks receiver mixing

All lessons in Expert