Real World Example

Logging and Timing Helpers

Production apps wrap risky work in small inline helpers: measure how long a block takes for analytics, and log failures with the type of the event. Because the helpers are inline, they add no lambda allocations on hot paths such as list scrolling, and reified gives the event type name for free.

Example

data class CheckoutEvent(val orderId: String, val amount: Int)
data class SearchEvent(val query: String)

val analytics = mutableListOf<String>()

inline fun <reified E : Any> track(event: E) {
    analytics += "${E::class.simpleName}: $event"
}

inline fun <T> timed(label: String, block: () -> T): T {
    val start = System.nanoTime()
    try {
        return block()
    } finally {
        val ms = (System.nanoTime() - start) / 1_000_000
        analytics += "timing $label: ${if (ms < 1000) "under 1 s" else "slow"}"
    }
}

inline fun <T> safely(default: T, block: () -> T): T = try {
    block()
} catch (e: Exception) {
    analytics += "error: ${e::class.simpleName} ${e.message}"
    default
}

fun main() {
    val results = timed("search") { listOf("iPhone 15", "iPhone 15 Pro").also { track(SearchEvent("iphone")) } }
    println("Results: $results")
    val amount = safely(0) { "1299x".toInt() }
    println("Parsed amount: $amount")
    track(CheckoutEvent("ORD-77", 1299))
    analytics.forEach(::println)
}

Output

Results: [iPhone 15, iPhone 15 Pro]
Parsed amount: 0
SearchEvent: SearchEvent(query=iphone)
timing search: under 1 s
error: NumberFormatException For input string: "1299x"
CheckoutEvent: CheckoutEvent(orderId=ORD-77, amount=1299)