Найти тему

Введение в функциональное программирование на Python

Оглавление

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

В чём разница между аргументами функции и её параметрами?

Недавно я слушал лекцию преподавателя одного из московских университетов и обратил внимание, что он использует термины "аргумент" и "параметр" функции в разных контекстах. Мне понравилось это разделение, и теперь я предлагаю всем освоить его, чтобы избежать путаницы между двумя очень похожими, но принципиально разными понятиями.

Итак:

Параметр функции - это название переменной, которую мы указываем в скобках при определении функции. Параметры абстрактны и существуют только внутри функции.

Аргумент функции - это конкретное значение, которые мы передаём в скобках при вызове функции.

Таким образом, аргументы и параметры - это разные понятия. Аргументы - это значения, которые назначаются заранее описанным параметрам.

Рассмотрим пример:

Наглядно об отличиях параметров и аргументов
Наглядно об отличиях параметров и аргументов

Скобки - это оператор вызова функции

Мы знаем много арифметических и логических операторов. Но важно понимать, что скобки во многих случаях также являются оператором, работающим с одним операндом (подобно оператору "not" в Python).

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

Функции можно:

  • Записывать в переменные.
  • Помещать в структуры данных, такие как списки и словари.
  • Передавать в качестве аргументов в другие функции.

Скобки необходимы только для вызова функции, чтобы "приказать" интерпретатору начать выполнение её кода. До тех пор, пока скобки не будут использованы, функция остаётся в "неактивированном" состоянии, и с ней можно работать, как со многими известными нам типами данных.

В примере мы видим, что в переменную "а" вложена ссылка на функцию "cube". Это похоже на то, как если бы мы поместили в переменную обычной объект
В примере мы видим, что в переменную "а" вложена ссылка на функцию "cube". Это похоже на то, как если бы мы поместили в переменную обычной объект

Функциональная и императивная парадигмы программирования

На самом деле, программировать можно по-разному. Всё зависит от того, как именно Вы смотрите на процесс решения задачи.

Самый простой способ решить задачу - это составить алгоритм, в котором будет описываться последовательность действий, которую должен выполнить исполнитель.

Как решить выражение (8+3)*7 - 1?

Алгоритм решения выражения:

1. Сложи 8 и 3.

2. Полученный результат умножь на 7.

3. Из полученного результата вычти 1.

Всё просто: действия выполняются последовательно шаг за шагом. И даже наличие условий и циклов этот принцип не нарушат. Именно так мы и привыкли программировать. Именно так мы и рассматриваем компьютерные программы - как набор последовательных приказов исполнителю.

Вышеописанный подход к написанию компьютерных программ называется императивной парадигмой программирования. "Императивный" означает "основанный на приказах (командах)", а "парадигма" - это подход, которого придерживается программист.

Кроме привычной нам императивной парадигмы программирования, существуют и другие.

Сегодня мы знакомимся с функциональным программированием. Функциональная парадигма, как можно догадаться, основана на функциях.

На самом деле, Python не является языком программирования, полностью поддерживающим функциональную парадигму программирования - в нём есть только её элементы. С этими элементами мы и знакомимся для использования в своих программах.

Основные идеи функционального программирования

Функции высших порядков

Мы уже обсудили, что в Python функции являются гражданами первого класса. Эта их особенность позволяет реализовать очень важную для функциональной парадигмы идею - создавать функции высших порядков.

Функция высшего порядка - это просто функция, которая в качестве аргумента может принимать другие функции.

Например, мы знакомы с функцией map(). Мы прекрасно помним, что её удобно использовать для преобразования списка строк в список чисел:

Функция map
Функция map

Какие аргументы принимает функция map?

Второй аргумент - это список со строками. А первый аргумент - это другая функция "int". Обращаю Ваше внимание, что скобок нет - функция не вызывается.

Поэтому map - это функция высшего порядка.

Рекурсия

Знание рекурсий проверяется в нескольких заданиях ЕГЭ по информатике. На мой взгляд, их самое интересное применение имеется в заданиях 19-21 про Петю, Ваню и кучи камней.

Просто напоминаю Вам о шаблоне решения задания.

Шаблон решения задания 19 с одной кучей
Шаблон решения задания 19 с одной кучей

Так вот это решение использует рекурсию. Более того, это решение является очень хорошим примером функциональной парадигмы программирования.

В целом, рекурсии являются важнейшей частью функционального программирования.

Чистые функции

Мы хотим писать понятные и простые для использования функции. Такие, как поиск синуса из библиотеки "math".

Понятность функции заключается в том, что её ответ будет всегда один и тот же при одинаковых значениях аргументов. Но иногда в коде можно встретить и такое:

Грязная функция
Грязная функция

В примере выше мы вызываем функцию f с аргументом 3 и каждый раз получаем разные ответы. Почему? Потому что результат выполнения функции зависит не только от аргумента, но и от списка lst.

Представьте, что функцию f написали не Вы - она была в какой-то используемой Вами библиотеки. Вы вызвали 4 раза функцию f с одним и тем же аргументом и получили 4 разных ответа. Как быстро Вы разберётесь в том, что происходит?

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

Заключение

Понимание основ функционального программирования позволит Вам перестать рассматривать решения некоторых задач ЕГЭ как набор готовых неизменяемых шаблонов. Также некоторые фишки ФП позволять сделать код намного короче.