skip to content

Generic Functions

A generic function declares its type parameter before the function name, and call sites almost always infer it. Knowing when inference fails — and how to pass an explicit type argument — is the practical takeaway.

part ofKotlinoverview, primer and where to startread it →
on this pageshow

questions

5

How do you declare a generic function in Kotlin, and where does the type parameter go relative to the function name?

level: juniorimportance: must knowfreq 80%

answer

  1. fun <T> name(...) — angle brackets BEFORE the name
  2. Class is opposite: class Box<T> (after the name)
  3. T usable in params, return type, and body
  4. Multiple: fun <K, V> ...
  5. Convention: T, R, K, V, E

basics

~10 s

You write the type name in angle brackets right before the function name, like fun <T> first(list: List<T>): T. T is a placeholder for any type the caller uses.

solid answer

~40 s

A generic function declares one or more type parameters in angle brackets placed before the function name: fun <T> firstOrNull(list: List<T>): T?. Unlike generic classes, where the parameter sits after the class name (class Box<T>), a function's parameter goes before its name because the name is also where the receiver/parameters begin. The type parameter T can then be used in the parameter types, return type, and body. You can declare several, e.g. fun <K, V> pair(k: K, v: V): Pair<K, V>. Type parameters are conventionally single uppercase letters (T, R, K, V). They let one function work over many types with full static type safety, avoiding casts. At the call site the compiler usually infers T from the arguments, so you rarely spell it out.

code

kotlin · 6 lines
kotlin
fun <T> firstOrNull(items: List<T>): T? = if (items.isEmpty()) null else items[0]

fun <K, V> singleEntryMap(k: K, v: V): Map<K, V> = mapOf(k to v)

// extension form — <T> still before the name
fun <T> T.echo(): T { println(this); return this }

go deeper

for a junior

Knows the exact syntax fun <T> name(...) and that <T> precedes the name; can write a simple identity/first function.

for a middle

Explains the position difference vs classes, uses multiple parameters, and applies generics to extension functions.

for a senior

Frames generics as static type safety without casts, knows erasure caveats, and uses idiomatic names plus generic extensions fluently.

for a principal

Reasons about API design: when a generic function vs overloads is appropriate, naming conventions for library readability, and erasure implications for callers.

## What a generic function is A **generic function** is a function parameterized by one or more **type parameters** — placeholders for types that are filled in per call. This lets a single function operate on many types while keeping full compile-time type safety (no `Object`/`Any` casts). ## Syntax: where the `<T>` goes For a function, the type-parameter list comes **immediately before the function name**: ```kotlin fun <T> identity(value: T): T = value fun <K, V> mapOfOne(key: K, value: V): Map<K, V> = mapOf(key to value) ``` Contrast this with a **generic class**, where the parameter list comes **after** the class name: `class Box<T>(val item: T)`. The difference is purely positional: a class name stands alone, so `<T>` follows it; a function name is followed by its parameter list `(...)`, so `<T>` must precede the name to stay unambiguous. ## Using the type parameter Once declared, `T` is in scope for: - **parameter types** — `value: T` - the **return type** — `: T` - the **function body** — you can declare locals of type `T`, call it, etc. You may declare multiple parameters separated by commas: `fun <A, B, C> ...`. Convention uses short uppercase names: `T` (type), `R` (result), `K`/`V` (key/value), `E` (element). ## Extension generic functions The receiver can also be generic: ```kotlin fun <T> T.alsoLog(): T { println(this); return this } ``` Here `<T>` is still before the name `alsoLog`, and `T` is used as the receiver type. ## Why it matters Without generics you'd either duplicate the function per type or accept/return `Any` and cast — losing type safety. Generics give one reusable, type-checked definition. Note: Kotlin generics are **erased** at runtime (like Java) unless the function is `inline` with a `reified` parameter — but that is a separate concern from simply declaring `fun <T>`.

  • Why does a generic function put <T> before the name while a generic class puts it after?
    A class name stands alone so <T> can follow it; a function name is immediately followed by its (...) parameter list, so the type parameters must precede the name to keep the grammar unambiguous.
  • Can a type parameter be used in the function's return type?
    Yes. Once declared in <...>, T is in scope for parameter types, the return type, and the body — e.g. fun <T> id(x: T): T = x.

The <T> before the name is like a blank you fill in on a form before reading the rest of the sentence.

saying these in an interview costs you the question

  • Writing fun identity<T>(...) — putting <T> after the name (that's class syntax)
  • Thinking generics require runtime type tokens for a plain fun <T>
  • Claiming you must always pass the type explicitly at the call site
  • Confusing the type parameter T with a regular value parameter
  • Saying T must be a specific type rather than a placeholder

context

open as a page

How does Kotlin infer the type argument of a generic function at a call site, and when does inference fail?

level: middleimportance: must knowfreq 70%

basics

~20 s

Kotlin guesses T from the values you pass in or from how the result is used, so you usually don't write the type yourself. It fails when there's nothing for it to read the type from.

open as a page

When and how do you pass explicit type arguments to a generic function, e.g. maxOf<Int>(...)? Why might you do it even when inference would work?

level: middleimportance: should knowfreq 55%

basics

~10 s

You write the type in angle brackets right after the function name, like maxOf<Int>(a, b). You do it when Kotlin can't figure the type out, or to force a specific type or improve clarity.

open as a page

At runtime, what happens to a generic function's type parameter T, and how does that limit what you can do with T inside the body?

level: seniorimportance: should knowfreq 50%

basics

~20 s

By default the type T is erased — it disappears at runtime — so inside the function you can't check or create T directly (no x is T, no T()). The type only exists at compile time.

open as a page

You need a function that returns the single element of a collection or throws. Would you write a generic function, and how does using a type parameter compare to writing per-type overloads or returning Any?

level: seniorimportance: nice to knowfreq 35%

basics

~10 s

Yes, write one generic function fun <T> single(c: Collection<T>): T. It works for every element type, returns the exact type, and avoids copy-pasting a version per type or returning Any and forcing casts.

open as a page