Higher-order function: wat het is, kenmerken en voorbeelden in Kotlin

Auteur: IT Sectr Gepubliceerd: 2026-06-23 Leestijd: 8 min

Higher-order function — is een functie die een andere functie als parameter accepteert of een functie als resultaat retourneert. In Kotlin zijn functies eersteklas objecten: ze kunnen worden opgeslagen in variabelen, doorgegeven als argumenten en geretourneerd. Volgens Kotlin-documentatie (2026) verminderen higher-order functions het dupliceren van code gemiddeld met 30% in vergelijking met imperatieve benaderingen. Higher-order function — een fundamenteel concept van de functionele stijl in moderne ontwikkeling.

Belangrijkste punten

  • Higher-order function — functie die een andere functie als parameter accepteert of retourneert
  • Functioneel type (T) -> R — basis voor het declareren van functieparameters in de handtekening
  • Lambda-expressie — compacte manier om een functie door te geven aan een higher-order function
  • Gedrag doorgeven maakt het mogelijk bewerkingen te parametriseren zonder overerving en interfaces
  • Functie retourneren uit higher-order function wordt toegepast voor fabrieken en closures

Wat is een higher-order function?

Higher-order function — is een functie die ten minste een van twee kenmerken heeft: het accepteren van een andere functie als argument of het retourneren van een functie als resultaat. In de wiskunde worden dergelijke functies functionalen of operatoren genoemd. In de programmering verschenen ze in Lisp in 1958 en werden ze een verplicht onderdeel van alle moderne talen — JavaScript, Python, Swift, Kotlin, Scala en Haskell. Higher-order function maakt het mogelijk om te abstraheren van een specifieke bewerking en gedrag als waarde door te geven.

Het belangrijkste verschil tussen een higher-order function en een gewone functie — de aanwezigheid van een parameter met een functioneel type of een geretourneerde functionele waarde. In Kotlin wordt het functionele type geschreven als (ParamType) -> ReturnType. Bijvoorbeeld, het type (Int) -> String betekent een functie die Int accepteert en String retourneert. Het type () -> Unit geeft een functie zonder parameters aan die geen nuttige waarde retourneert. Juist dit typesysteem maakt higher-order functions typeveilig.

Het tegenovergestelde van een higher-order function — first-class function (eersteklas functie). First-class function betekent dat een functie als elke andere waarde kan worden gebruikt: toegewezen aan een variabele, opgeslagen in een collectie, doorgegeven als argument. Higher-order function is een functie die first-class functions gebruikt om te accepteren of te retourneren. Kotlin ondersteunt beide concepten op taalniveau zonder extra bibliotheken.

Hoe werkt een higher-order function in Kotlin?

In Kotlin wordt elke functie die ten minste één parameter heeft gedeclareerd met een functioneel type of waarvan het retourtype functioneel is, automatisch beschouwd als een higher-order function. De compiler vereist geen speciale annotatie — het is voldoende om (T) -> R in de handtekening te specificeren. Bij het aanroepen van zo'n functie wordt als argument ofwel een lambda-expressie, ofwel een verwijzing naar een bestaande functie via ::, ofwel een functionele waarde opgeslagen in een variabele doorgegeven.

kotlin
fun operate(a: Int, b: Int, op: (Int, Int) -> Int): Int {
    return op(a, b)
}

fun main() {
    val sum = operate(10, 20) { x, y -> x + y }
    println(sum) // 30
}

In de listing accepteert de functie operate twee gehele getallen en de parameter op van het type (Int, Int) -> Int. Het lichaam van de functie roept in één regel de doorgegeven bewerking aan. In main geeft de aanroep operate de lambda { x, y -> x + y } door — Kotlin plaatst deze na de haakjes dankzij de trailing lambda-syntax. Als de lambda het laatste argument was, zou deze volledig buiten de haakjes kunnen worden geplaatst, wat de leesbaarheid van aanroepketens verhoogt.

Onder de motorkap compileert Kotlin de higher-order function via de Function-interface (Function2 voor twee parameters). Elke lambda wordt omgezet in een anonieme klasse die de bijbehorende FunctionN-interface implementeert. Dit betekent dat het maken van een lambda leidt tot toewijzing van een object voor elke bewerking. Om overhead te verminderen, ondersteunt Kotlin inline-functies, die het lichaam van de higher-order function op de aanroepplaats invoegen, waardoor het maken van een anonieme klasse wordt geëlimineerd.

Functies als parameters: gedrag doorgeven

Het doorgeven van een functie als argument — het meest voorkomende patroon voor het gebruik van een higher-order function. In plaats van een hiërarchie van klassen met een polymorfe methode te creëren, geeft de programmeur het gewenste gedrag rechtstreeks op het gebruikspunt door. Dit implementeert het Open/Gesloten Principe (Open/Closed Principle) zonder overerving: een nieuwe bewerking wordt toegevoegd als een nieuwe lambda, niet als een nieuwe subklasse.

Voor nullable-functies gebruikt Kotlin het type ((T) -> R)? met een vraagteken na de haakjes. Zo'n functie kan alleen worden aangeroepen na een null-controle of via de operator ?.invoke(). De handtekening van de higher-order function geeft duidelijk aan dat het doorgeven van de functie niet verplicht is — de aanroepende code kan het argument weglaten. Dit is handig voor callbacks en gebeurtenishandlers met optioneel gedrag.

kotlin
fun <T> List<T>.customFilter(
    predicate: (T) -> Boolean
): List<T> {
    val result = mutableListOf<T>()
    for (item in this) {
        if (predicate(item)) result.add(item)
    }
    return result
}

fun main() {
    val numbers = listOf(1, 2, 3, 4, 5)
    val even = numbers.customFilter { it % 2 == 0 }
    println(even) // [2, 4]
}

De extensiefunctie customFilter accepteert de parameter predicate van het functionele type (T) -> Boolean. Binnen de lus roept het predicate aan voor elk element en verzamelt de overeenkomende. De aanroep in main geeft de lambda { it % 2 == 0 } door, waarbij it de impliciete naam is van de enige parameter van de lambda. Dankzij de higher-order function is de filterlogica volledig gescheiden van het mechanisme om de collectie te doorlopen.

Functies als retourwaarden

Een higher-order function kan een functie retourneren — zo'n patroon wordt een functiefabriek of gedragsgenerator genoemd. De geretourneerde functie kan variabelen uit het externe bereik vastleggen (closure) en ze tussen aanroepen behouden. Dit maakt het mogelijk om configureerbare handlers en gespecialiseerde bewerkingen te creëren op basis van algemene sjablonen.

Bij het retourneren van een functie leidt Kotlin het geretourneerde functionele type ((T) -> R)? af uit de handtekening. De compiler controleert dat alle return-expressies in het lichaam compatibele functionele waarden retourneren. Vastgelegde variabelen worden opgeslagen in het lambda-object en zijn toegankelijk zolang er een verwijzing naar bestaat. Dit is een krachtig mechanisme, maar vereist aandacht bij geheugenbeheer.

kotlin
fun makeMultiplier(factor: Int): (Int) -> Int {
    return { x -> x * factor }
}

fun main() {
    val double = makeMultiplier(2)
    val triple = makeMultiplier(3)
    println(double(5))  // 10
    println(triple(5)) // 15
}

De functie makeMultiplier accepteert factor en retourneert de lambda { x -> x * factor }, waarbij factor is vastgelegd uit het externe bereik (closure). Bij elke aanroep van makeMultiplier wordt een nieuwe functie gemaakt met zijn eigen factor-waarde. De variabelen double en triple slaan de geretourneerde functies op en kunnen meerdere keren worden aangeroepen. Dit patroon wordt veel gebruikt bij het configureren van HTTP-cliënten, decorators en middleware.

Higher-order function met lambdas: voorbeelden

Gecombineerd gebruik van higher-order function en lambdas maakt het mogelijk om expressieve bewerkingsketens te bouwen zonder tussenliggende variabelen. De standaardbibliotheek van Kotlin bevat tientallen higher-order functions: let, run, apply, also, filter, map, flatMap, fold, reduce, forEach, groupBy en andere. Elk van hen accepteert een lambda en voert daarmee gegevenstransformatie uit.

kotlin
data class User(val name: String, val age: Int)

fun main() {
    val users = listOf(
        User("Alice", 25),
        User("Bob", 17),
        User("Charlie", 30)
    )

    val result = users
        .filter { it.age >= 18 }
        .map { it.name.uppercase() }
        .sorted()
    println(result) // [ALICE, CHARLIE]
}

In het voorbeeld verwerkt een keten van drie higher-order functions een lijst met gebruikers. filter accepteert een predicaat en houdt alleen meerderjarige gebruikers over. map transformeert elke gebruiker naar een naam in hoofdletters. sorted sorteert het resultaat oplopend. Elke bewerking accepteert een lambda en Kotlin zorgt voor typeveiligheid in alle fasen. Zonder higher-order function zou een lus met if, tijdelijke lijsten en handmatig sorteren moeten worden geschreven.

Veelgestelde vragen

Waarin verschilt een higher-order function van een gewone functie?

Higher-order function accepteert een andere functie als parameter of retourneert deze. Een gewone functie werkt alleen met gegevens — getallen, strings, objecten. Een higher-order function werkt met gedrag en geeft logica door als argument.

Kan een higher-order function inline zijn?

Ja, de inline-modificator elimineert de overhead van het maken van een anonieme klasse voor de lambda. Met crossinline of noinline kan worden beheerd welke lambdas worden ingevoegd en welke objecten blijven.

Wat is het functionele type van een functie zonder parameters?

Een functie zonder parameters en zonder retourwaarde heeft het type () -> Unit. Een functie met één parameter van type T en retournering R wordt geschreven als (T) -> R. Voor twee parameters — (T, U) -> R en zo verder tot 22 argumenten.

Wat is het verschil tussen een lambda en een anonieme functie?

Lambda — compacte notatie { args -> body }, anonieme functie — fun(args): ReturnType { body }. Lambda kan geen return zonder label hebben, anonieme functie wel. Beide kunnen worden doorgegeven aan een higher-order function.

Wanneer moet een higher-order function worden vermeden?

Vermijd higher-order functions in hete lussen zonder inline — elke lambda creëert een object. Gebruik voor kritieke prestaties inline fun. Misbruik ook geen diepe nesting van lambdas — dit vermindert de leesbaarheid.

Samenvatting

  • Higher-order function — functie die een andere functie als parameter accepteert of retourneert; fundament van functioneel programmeren in Kotlin
  • Functioneel type (T) -> R declareert een functieparameter met een typeveilige handtekening
  • Lambda-expressie — compacte syntax { args -> body } voor het doorgeven van gedrag
  • Inline-functies elimineren de overhead van het maken van anonieme klassen voor lambdas
  • Functiefabrieken retourneren een functie met vastgelegde context via het closure-mechanisme
  • Bewerkingsketens filter-map-sorted worden gebouwd op higher-order functions zonder tussenliggende variabelen
  • Typeveiligheid van higher-order function wordt gegarandeerd door het systeem van functionele types in Kotlin tijdens compilatie

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook