Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Современные языки программирования обладают большим набором разнообразных средств и удобных фишек, что позволяет писать совершенно разный код на одном и том же языке для одной и той же задачи.
Парадигма программирования — это в первую очередь стиль мышления: то, как программист думает о представлении данных и процессе их обработки. Другими словами, парадигма живёт в голове программиста, а не является свойством языка. Разные языки могут в той или иной степени поддерживать определённую парадигму. Если сейчас зайти на Википедию и начать читать про самые популярные ЯП, мы увидим, что многие из них заявлены как "мультипарадигменные": на них можно писать в разных стилях, но какие-то из них использовать будет удобнее.
В своей недавней статье мы рассказывали о практических применениях Лиспа и упомянули, что он сильно повлиял на развитие других языков программирования, но не стали вдаваться в детали. Пришло время более подробно раскрыть эту тему и разобраться, какой вклад функциональное программирование в целом (не только Лисп!) внесло в развитие других языков. Поскольку мы используем Haskell как основной язык разработки, и наша команда разработчиков состоит из ФП-энузиастов, мы не смогли пройти мимо такой темы.
В этом посте рассмотрим несколько механизмов, которые либо зародились в ФП-языках, либо нашли в них наибольшее применение и были ими популяризованы, и в итоге появились в языках, изначально не функциональных.
Функции первого класса
Отличительная особенность ФП-стиля в целом — это широкое применение функций, которые становятся одним из самый главных инструментов разработки. Давайте быстро пробежимся по основным определениям, которые описывают различия функций от процедур и других похожих конструкций из не-функциональных языков.
Функция высшего порядка (higher-order function) — это такая функция которая либо принимает другую функцию в виде аргумента либо возвращает функцию в результате. Их ещё называют функционалами. Такое поведение можно реализовать даже в чистом С, используя указатели на функции:
void update_user_balance(int user_id, double (*update_fn)(double)) {
// ...
user->balance = update_fn(user->balance);
// ...
}
Функция первого класса (first-class function) — те, которыми можно манипулировать как со всеми другими значениями: передавать как аргументы, возвращать в качестве результата, присваивать переменным и полям структур.
Безымянная функция (lambda function) — это функция без названия