Function types read like TypeScript's with -> for =>: (Book) -> Boolean, or () -> Unit for a callback that returns nothing. typealias names one, :: turns a function or property into a value (::isBargain, Book::inStock), and a function can return a lambda that remembers its arguments.
typealias BookFilter = (Book) -> Boolean
fun isBargain(book: Book) = book.price < 20.0
fun priceAbove(limit: Double): BookFilter = { it.price > limit } // returns a function
fun main() {
val filters = mapOf("bargain" to ::isBargain, "premium" to priceAbove(20.0))
for ((name, filter) in filters) println("$name: ${catalog.count(filter)}")
var onAddToCart: ((Book) -> Unit)? = null
onAddToCart?.invoke(catalog[0]) // no handler yet: nothing happens
onAddToCart = { println("Added ${it.title}") }
onAddToCart(catalog[0]) // smart cast: non-null here
}Output
bargain: 3 premium: 3 Added The Quiet Harbor
An optional callback has a nullable function type, ((Book) -> Unit)?, called with ?.invoke() (Safe Call and Elvis). Types are enforced: assigning Book::title to a BookFilter is a type mismatch, where JavaScript would accept a truthy string. Compose 234 's onClick: () -> Unit is a plain function type, so a screen can pass viewModel::addToCart straight down.