Что такое функция высшего порядка (higher-order function)?

Ответ

Функция высшего порядка — это функция, которая соответствует одному или двум условиям:

  1. Принимает одну или несколько функций (замыканий) в качестве аргументов.
  2. Возвращает функцию в качестве результата.

Это ключевая концепция функционального программирования, позволяющая создавать гибкие и переиспользуемые абстракции.

Примеры встроенных функций высшего порядка в Swift (для коллекций):

let numbers = [1, 2, 3, 4, 5]

// map — принимает функцию преобразования, возвращает новый массив.
let squared = numbers.map { $0 * $0 } // [1, 4, 9, 16, 25]

// filter — принимает функцию-предикат, возвращает отфильтрованный массив.
let evens = numbers.filter { $0 % 2 == 0 } // [2, 4]

// reduce — принимает начальное значение и функцию-комбинатор.
let sum = numbers.reduce(0, +) // 15

Пример кастомной функции высшего порядка:

// Функция, которая применяет другую функцию дважды.
func applyTwice(_ transform: (Int) -> Int, to value: Int) -> Int {
    return transform(transform(value))
}

let double = { $0 * 2 }
let result = applyTwice(double, to: 5) // 20 (5 * 2 * 2)

Пример функции, возвращающей функцию:

// Функция создает и возвращает функцию-приветствие.
func greeter(for name: String) -> () -> String {
    return { "Hello, (name)!" }
}

let greetAlice = greeter(for: "Alice")
print(greetAlice()) // "Hello, Alice!"

Преимущества: повышение уровня абстракции, устранение дублирования кода, удобство работы с асинхронными операциями (например, completion handlers).

Ответ 18+ 🔞

А, слушай, вот это тема — функции высшего порядка! Это ж, блядь, как в армии: есть солдаты, а есть прапорщик, который ими командует. Так и тут — есть обычные функции, а есть эта, с прибабахом, которая либо принимает других на работу, либо плодит их, как кроликов, и выдаёт тебе на руки.

Если по-простому, то функция высшего порядка — это такая хитрая жопа, которая:

  1. Может засунуть себе в аргументы другую функцию (ну или замыкание, что по сути одно и то же, только компактнее).
  2. Или может высидеть и выдать тебе на гора готовую функцию, как курица яйцо.

Это, блядь, основа основ функциональщины. Без этого — нихуя не гибко и не красиво.

Смотри, какие у нас в Swift уже готовые красавцы живут, прямо в стандартной библиотеке:

let numbers = [1, 2, 3, 4, 5]

// map — это как конвейер: берёт каждый элемент и пропускает через твою функцию-извращение.
let squared = numbers.map { $0 * $0 } // [1, 4, 9, 16, 25]

// filter — это швейцар в клубе: пропускает только тех, кто соответствует условию.
let evens = numbers.filter { $0 % 2 == 0 } // [2, 4]

// reduce — это скряга: скукоживает весь массив в одно значение, плюсуя всё нахуй.
let sum = numbers.reduce(0, +) // 15

А вот если хочешь свою, доморощенную, высшего порядка — пожалуйста, делай! Вот, смотри, функция-садист, которая применяет твоё преобразование дважды, ебать её в сраку:

// Берёт функцию и значение, и долбит его этой функцией два раза подряд.
func applyTwice(_ transform: (Int) -> Int, to value: Int) -> Int {
    return transform(transform(value)) // Ёпта, вот это закручено!
}

let double = { $0 * 2 }
let result = applyTwice(double, to: 5) // 20 (5 * 2 = 10, 10 * 2 = 20)

А бывает и наоборот — функция как фабрика по производству других функций. Как автомат по продаже кофе: кинул имя — получил замыкание-приветствие.

// Эта штука не делает ничего сама, она только плодит других.
func greeter(for name: String) -> () -> String {
    return { "Hello, (name)!" } // Вот, получай свою персональную функцию, довольствуйся.
}

let greetAlice = greeter(for: "Alice") // greetAlice теперь — готовая функция!
print(greetAlice()) // "Hello, Alice!"

В чём, сука, соль-то? А соль в том, что код становится, блядь, как конструктор «Лего». Меньше дублирования, больше переиспользования, и асинхронщину всякую (типа completion handlers) организовывать — одно удовольствие. В общем, мощный инструмент, хоть и мозг поначалу может слегка ебнуть.