Ключевое слово function и отсутствие неявного return заставляют код выглядеть немного громоздким. Но, тем не менее, он работает. Еще один «строительный блок» в копилку для функционального программирования.
array_map(function ($x) {return $x * 2;}, [1, 2, 3]);
Как видно из примеров, для строго типизированного языка программирования синтаксис всегда остается довольно компактен. Перепишем наш пример на PHP:
List(1, 2, 3).map((x: Int) => x * 2)
Тоже неплохо, хоть нам и пришлось использовать блок и нестрогое лямбда-выражение. У Ruby тоже есть лямбда-выражения, но List.maphappens принимает блок, а не функцию. Перейдем к Scala:
Симпатично, теперь взглянем на тот же код для Ruby:
map(lambda v: v * 2, [1, 2, 3])
PHP в том числе поддерживает анонимные функции. Как упоминалось ранее, сообщество Haskell от души смеется над этим фактом, но главного все равно не отнять мы наконец-то их получили. Да и шутки были вполне ожидаемы, потому что синтаксис выражений стал очень тяжелым. Возьмем простой пример на Python.
В PHP 5.4 появился новый тип callable , который позволяет простой доступ к мета-типу callable.
$print("Hello %s\n", 'World');
Тем не менее, здесь есть несколько интересных «строительных блоков» для целей функционального программирования. Для начала, возьмем call_user_func, call_user_func_array и $callable(). call_user_func принимает callback-функцию и список аргументов, после чего вызывает этот callback с переданными аргументами. call_user_func_array делает то же самое, за исключением того, что она принимает массив аргументов. Это очень похоже на fn.call() и fn.apply() в JavaScript (без передачи области видимости). Гораздо менее известная, но отличная функция в PHP 5.4 это возможность вызывать функции. callable это мета-тип в PHP (то есть состоящий из нескольких вложенных типов): callable может быть строкой для вызова простых функций, массивом из <string,string> для вызова статичных методов и массивом из <object,string> для вызова методов объекта, экземпляра Closure или чего угодно, осуществляющего магический метод __invoke(), также известный как Функтор. Это выглядит примерно следующим образом:
PHP не является «настоящим» или «чистым» функциональным языком. Он далек от этого. Здесь нет надлежащей системы типов, " " катаются со смеху от нашего экзотического синтаксиса для замыканий, а еще тут есть функция array_walk(), которая на первый взгляд выглядит функциональной, но позволяет изменение состояний.
Что может предложить PHP?
Функциональное программирование обладает несколькими соблазнительными свойствами: отсутствие возни с состояниями делает параллелизм проще (но не простым параллелизм никогда не бывает простым), фокусировка на функции на минимальной единице кода, который можно было бы использовать снова может привести к интересным вещам, связанным с их повторным использованием; требование к функциям быть определенными это отличная идея для создания стабильных программ.
Типичный функциональный язык программирования поддерживает также функции высокого порядка это функции, которые принимают в качестве аргументов или возвращают другие функции. Большинство из них поддерживает такие вещи, как карринг (currying) и частичное применение функции (partial function application). Также в языках функционального программирования можно встретить тщательно продуманную систему типов, которые используют для предотвращения появления нулевых указателей, которые стали обычным делом для императивных или объектно-ориентированных языков программирования.
Прошло уже несколько лет с тех пор, как я начал использовать функциональные элементы в своем исходном коде, но я все еще не готов дать прямого и точного ответа на этот вопрос. И все же, несмотря на то, что у меня пока что нет четкого определения я с уверенностью могу сказать, когда передо мной пример функционального программирования, а когда нет. Поэтому я попробую зайти немного с другой стороны: функциональные программы обычно не прибегают к изменению состояний, а используют чистые функции. Эти чистые функции принимают значение и возвращают значение без изменения своего входного аргумента. Противоположный пример это типичный сеттер в объектно-ориентированном контексте.
Что же это все-таки такое функциональное программирование?
PHP всегда был простым, процедурным языком программирования, черпавшим свое вдохновение из C и Perl. В PHP 5 появилась правильная объектная модель, но о ней вы уже все знаете. А вот в PHP 5.3 появились замыкания (closure), которые были серьезно улучшены в версии 5.4 (подсказка: $this теперь доступен по умолчанию).
Функциональное программирование на PHP
Функциональное программирование на PHP / Хабрахабр
Комментариев нет:
Отправить комментарий