PHP: Функции

Парадигмы программирования

В программировании часто используется термин "парадигма".

Паради́гма программи́рования — это совокупность идей и понятий, определяющих стиль написания компьютерных программ (подход к программированию). Это способ концептуализации, определяющий организацию вычислений и структурирование работы, выполняемой компьютером. (Wikipedia)

Парадигма — это больше, чем просто другой алгоритм решения задачи. Как правило, структура кода при использовании разных парадигм отличается очень значительно и требует знаний, выходящих за рамки только синтаксиса языка (например, автоматное программирование требует хотя бы базового понимания теории автоматов). Причём подавляющее большинство современных (и не очень) языков программирования являются мультипарадигменными и позволяют писать код, используя множество стилей. Иногда эти стили взаимоисключающие, иногда они дополняют друг друга. К текущему моменту мы писали код, используя две парадигмы: императивную и декларативную.

Paradigms

Императивная парадигма

Императивная парадигма — стиль написания кода в виде набора последовательных инструкций (команд) с активным использованием переменных. Возможно, данное определение звучит страшно, но на практике императивный стиль является доминирующим. Не считая этого курса, весь остальной код мы писали именно в императивном стиле.

<?php

// Поиск максимального числа
$numbers = [10, 20, 52, 105, 56, 89, 96];

$max = $numbers[0];
foreach ($numbers as $number) {
    if ($number > $max) {
        $max = $number;
    }
}

print_r($max); // => 105

В императивном стиле широко используется присваивание (а, значит, и переменные) и циклы. Эта парадигма популярна потому, что она в точности соответствует тому, как работает компьютер: последовательно выполняет инструкции и использует память для хранения промежуточных результатов. Обычно говорят, что императивная программа отвечает на вопрос КАК («как достичь нужного результата»).

PHP как, впрочем и Java/Ruby/Python/C#/Perl/JavaScript/Go, относится к императивным языкам. То есть языкам, в которых доминирующей является императивная парадигма (язык толкает к её использованию). Что, однако, не мешает использовать и другие парадигмы в рамках этих языков.

Декларативная парадигма

Императивному стилю противопоставляют декларативный, который нередко называют функциональным. Ключевое отличие функционального стиля от императивного в том, что при таком стиле программа выглядит как описание нужного результата, а не как набор инструкций. То есть программа отвечает на вопрос ЧТО («что мы хотим получить»). Эту грань довольно трудно уловить сразу, но, например, вся математика по своей сути декларативна. Например математическое определение факториала фактически является декларативным кодом:

<?php

function factorial($number)
{ 
    if ($number <= 1) {
        return 1;
    } else {
        return $number * factorial($number - 1);
    }
}

Пример с поиском максимального числа:

<?php

$numbers = [10, 20, 52, 105, 56, 89, 96];
$max = array_reduce(
    $numbers,
    fn($acc, $number) => $number > $acc ? $number : $acc,
    $numbers[0]
);
print_r($max); // => 105

Главное отличие декларативной парадигмы от императивной на практике - отсутствие присваивания. Вы можете возразить, что в коде выше переменные есть и чисто технически это правда. Присмотритесь к коду внимательнее, вы заметите что переменная создана ровно один раз и больше не меняется. По сути, она рассматривается как константа или, если копнуть глубже, как логическое высказывание. В математике это звучало бы так: допустим "A — это множество чисел". Что бы мы дальше ни делали, "A" остаётся всегда тем же, чем было во время определения.

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

То же самое касается и $acc с $number. Эти параметры всегда определяются ровно один раз, так как каждый вызов функции при таком определении (без использования ссылок) не зависит от другого вызова (спасибо чистым функциям). В мире функциональных языков такую операцию называют связывание. Визуально оно выглядит как присваивание, но это не оно. Попытка связать уже связанный идентификатор (в функциональных языках нет переменных) завершится ошибкой. Ниже пример на языке Erlang:

1> A = 4.
4
2> A = 'hey'.
** exception error: no match of right hand side value hey

Отсутствие присваивания автоматически означает то, что в функциональной парадигме невозможно использование циклов. Вместо них используется рекурсия. Другой важной особенностью функционального стиля считается активное использование функций как объектов первого рода. В основном в функциях высшего порядка. Причём они способны заменить рекурсию в подавляющем большинстве задач, в чем мы уже убедились в предыдущих уроках (убедились так, что даже не рассматривали рекурсию). Любая задача из представленных решалась основной тройкой функций высшего порядка.

Языков, использующих декларативную парадигму, довольно много. Они, в своей массе, менее популярны, чем императивные, но прочно занимают определённые ниши и активно используются в промышленном программировании. К таким языкам относятся: Haskell/Erlang/Elixir/OCaml/F#. В этих языках нет присваивания и циклов. Императивный код на них написать просто невозможно. Немного особняком стоят такие языки, как Scala и Clojure (и другие из семейства LISP). В этих языках основная парадигма — декларативная, и язык толкает к тому, чтобы писать в таком стиле, но при необходимости на них можно написать самый настоящий императивный код с присваиванием и циклами. А вот почти все императивные языки позволяют писать декларативно. Причём, если одни языки имеют довольно слабую поддержку декларативной парадигмы, то другие настолько мощную, что в них можно писать только декларативно (если хочется). К последним относится и современный JavaScript.

В PHP поддержка функционального программирования слабее, чем в большинстве других языков, но все же она достаточно серьёзная. С каждой новой версией PHP вбирает в себя все больше и больше возможностей, взятых из функциональных языков, многие из которых достаточно быстро становятся популярными и начинают использоваться повсеместно, например, лямбда-функции. С другой стороны, в PHP невозможно обновить массив не используя присваивания (говорят, «в иммутабельном (неизменяемом) стиле»). Поэтому любой код на PHP использующий функциональные возможности, так или иначе имеет императивные куски.

Другие парадигмы

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

  • Логическое программирование
  • Автоматное программирование
  • Объектно-ориентированное программирование
  • Метапрограммирование

Дополнительные материалы

  1. Парадигмы
  2. Функциональное программирование в PHP
  3. Ссылочная (референциальная) прозрачность

<span class="translation_missing" title="translation missing: ru.web.courses.lessons.mentors.mentor_avatars">Mentor Avatars</span>

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.
Об обучении на Хекслете

Для полного доступа к курсу нужна профессиональная подписка

Профессиональная подписка откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
115
курсов
892
упражнения
2241
час теории
3196
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 115 курсов, 2000+ часов теории
  • 800 практических заданий в браузере
  • 250 000 студентов

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг».

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Rambler
Логотип компании Bookmate
Логотип компании Botmother

Есть вопрос или хотите участвовать в обсуждении?

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг».