Question

Mark Unused Callback Parameters in Kotlin

kotlinsuppress-warningsunused-variables

Question

I am defining Kotlin functions to use as callbacks, but some callback implementations do not need every parameter they receive.

How can I indicate that a parameter is intentionally unused so the compiler or IDE does not report an unused-parameter warning?

Short Answer

You will learn how Kotlin handles intentionally unused callback parameters. In particular, you will know when to use @Suppress("UNUSED_PARAMETER") for named functions and _ for lambda parameters, while preserving the callback signature required by an API.

Concept

A callback is code that another function, framework, or API calls later. The API defines the callback's signature: its parameter types, order, and return type.

Sometimes your implementation must accept a parameter to match that signature even though it does not need the value. For example, a click listener may provide both a view and an event, while your handler only needs the event.

Kotlin and IDE inspections can flag such parameters as unused because unused values may indicate a mistake. When the parameter is intentionally unused, make that intent explicit:

  • Use @Suppress("UNUSED_PARAMETER") on a named function or on an individual parameter.
  • Use _ for unused parameters in a lambda.

This keeps required callback contracts intact while making the code's intent clear.

Mental Model

Think of a callback signature as a delivery form that must contain certain fields. A delivery service always gives you the recipient name, address, and tracking number. If you only need the address, you still receive the other fields because that is the agreed form.

For a named Kotlin function, @Suppress("UNUSED_PARAMETER") is a note saying, “I received this field on purpose, but do not need it.”

For a lambda, _ is like leaving a field unnamed because you know you will not use it.

Take Quiz

Syntax and Examples

For a named function, keep the required parameter and suppress the warning:

@Suppress("UNUSED_PARAMETER")
fun logConnectionStatus(connectionId: String, isConnected: Boolean) {
    println("Connected: $isConnected")
}

The function still accepts connectionId, so it can match a callback expecting (String, Boolean) -> Unit. The annotation states that leaving connectionId unused is intentional.

You can suppress only one parameter instead of the whole function:

fun logConnectionStatus(
    @Suppress("UNUSED_PARAMETER") connectionId: String,
    isConnected: Boolean
) {
    println("Connected: $isConnected")
}

For a lambda, use _ in the parameter position:

val printStatus: (String, Boolean) -> Unit = { _, isConnected ->
    println("Connected: $isConnected")
}

Here, _ means the first lambda argument is deliberately ignored. It cannot be referenced inside the lambda body.

Step by Step Execution

Consider this callback type:

val onResult: (Int, String) -> Unit = { _, message ->
    println(message)
}

onResult(200, "Saved successfully")

Execution proceeds as follows:

  1. onResult is declared as a function that receives an Int and a String and returns Unit.
  2. The lambda uses _ for the first argument, so the status code is accepted but intentionally ignored.
  3. The second argument is named message, because the lambda needs it.
  4. Calling onResult(200, "Saved successfully") passes both required arguments.
  5. 200 is discarded by _.
  6. message receives "Saved successfully", and the program prints it.

Output:

Saved successfully

Real World Use Cases

Intentional unused parameters are common when implementing fixed callback contracts:

  • UI listeners: A listener provides a UI component and an event, but the handler only needs one of them.
  • Collection processing: mapIndexed provides an index and value, but the index may not matter.
  • Network callbacks: A response handler may receive a request ID, status code, and body, while only the body is useful.
  • Framework lifecycle methods: A framework requires context or state parameters that a particular implementation does not need.
  • Event handlers: An event system may supply metadata, timestamps, or source objects that some handlers ignore.

Example with mapIndexed:

val names = listOf("Ada", "Lin", "Mina")
val greetings = names.mapIndexed { _, name ->
    "Hello, $name"
}

println(greetings)
Take Quiz

Real Codebase Usage

In production code, developers usually choose the clearest option based on the callback form.

Lambdas: prefer _

Use _ when a lambda receives an argument that is not needed:

val validEmails = emails.filter { _, email ->
    email.contains("@")
}

However, filter actually supplies only one argument, so this would not compile. For APIs that really provide two values, such as mapIndexed, _ is appropriate:

val labels = users.mapIndexed { _, user -> user.name }

Named callback functions: use targeted suppression

When a framework requires a named function, suppress only the specific parameter where possible:

fun handleResponse(
    @Suppress("UNUSED_PARAMETER") requestId: String,
    body: String
) {
    println(body)
}

Targeted suppression communicates that body is important while requestId is part of the required interface only.

Do not remove required parameters

A callback must match the type expected by the code that invokes it. Removing parameters changes the function type and can prevent it from being passed as a callback.

Common Mistakes

Removing a required callback parameter

This changes the function's type:

// Expected callback type: (String, Boolean) -> Unit
fun printStatus(isConnected: Boolean) {
    println(isConnected)
}

This function has type (Boolean) -> Unit, not (String, Boolean) -> Unit. Keep the required parameter and suppress its warning instead.

@Suppress("UNUSED_PARAMETER")
fun printStatus(connectionId: String, isConnected: Boolean) {
    println(isConnected)
}

Using _ in a named function parameter list

_ is the idiomatic ignored-parameter marker for lambda parameters. For ordinary named functions, use a normal parameter name and @Suppress("UNUSED_PARAMETER").

fun handle(@Suppress("UNUSED_PARAMETER") event: String) {
    println("Handled")
}

Trying to use _ later in a lambda

_ has no variable name, so it cannot be read:

val callback: (Int, String) -> Unit = { _, message ->
    // println(_) // Does not compile
    println(message)
}

Give the parameter a real name if you may need it.

Suppressing too broadly

Avoid suppressing warnings for an entire file unless that is truly necessary. A parameter-level suppression is more precise and makes accidental unused parameters easier to notice.

Comparisons

SituationRecommended approachWhy
Lambda parameter is unused_Clearly shows that one lambda argument is ignored.
Named function parameter is unused@Suppress("UNUSED_PARAMETER")Keeps the required function signature and documents intent.
Parameter may be needed laterGive it a descriptive nameYou can reference it and avoid changing the signature later.
Callback API allows fewer parametersUse a smaller lambda if the expected type permits itOnly do this when it still matches the API's expected function type.

_ and @Suppress("UNUSED_PARAMETER") solve related but distinct situations: _ is syntax for an ignored lambda argument, while @Suppress controls warnings for declarations, including named function parameters.

Take Quiz

Cheat Sheet

// Named function: suppress all unused-parameter warnings in this function
@Suppress("UNUSED_PARAMETER")
fun callback(id: String, value: Int) {
    println(value)
}

// Named function: suppress one parameter only
fun callback(@Suppress("UNUSED_PARAMETER") id: String, value: Int) {
    println(value)
}

// Lambda: ignore one argument
val callback: (String, Int) -> Unit = { _, value ->
    println(value)
}
  • A callback must retain the parameter types and order required by its expected function type.
  • Use _ only for ignored lambda parameters.
  • _ cannot be referenced in the lambda body.
  • Prefer parameter-level @Suppress("UNUSED_PARAMETER") when only one named-function parameter is unused.
  • Do not suppress warnings broadly when a narrower suppression is enough.

FAQ

How do I ignore a parameter in a Kotlin lambda?

Use _ in its parameter position.

val handler: (Int, String) -> Unit = { _, text -> println(text) }

How do I suppress an unused parameter warning in a Kotlin function?

Add @Suppress("UNUSED_PARAMETER") to the function or directly to the unused parameter.

Can I remove an unused parameter from a callback function?

Only if the API accepts the resulting smaller function type. If the callback contract requires the parameter, removing it prevents the function from matching that contract.

Can I use _ inside a lambda body?

No. _ means “ignore this value,” so it does not create a variable you can access.

Should I use @Suppress on the function or the parameter?

Prefer annotating the individual parameter when possible. It is more specific and avoids hiding warnings for other parameters.

Is an unused parameter always safe to ignore?

Not necessarily. First verify that it is genuinely irrelevant. A warning can reveal that you forgot to use an important input, such as an error code or validation result.

Take Quiz

Mini Project

Description

Create a small event-processing example in which every event handler receives an event ID and message, but one handler only needs the message. This mirrors logging, notification, and API callback code where a shared callback signature carries more information than every handler uses.

Goal

Define and invoke Kotlin callbacks while clearly ignoring an unneeded lambda parameter.

Requirements

  1. Define a callback type that accepts an event ID and a message.
  2. Create one callback that prints only the message.
  3. Mark the unused lambda argument with _.
  4. Create another callback that uses both arguments.
  5. Invoke both callbacks with sample event data.
Take Quiz

Keep learning

Related questions

View more