solit 2014, functional programming, Соловей Василий

4
Functional programming Важные аспекты функционального программирования Начнём с терминов. Википедия определяет функциональное программирование как “парадигму программирования, в которой процесс вычисления трактуется как вычисление значений функций в математическом понимании последних”. В данном способе программирования главным объектом манипуляции являются функции, в то время как в императивном программировании главным принципом является последовательное выполнение команд для достижения желаемого результата. Когда я сказал, что главным объектом манипуляции являются функции, я имел в виду, что с ними мы можем делать всё, что угодно: передавать как аргументы в другие функции, определять функции в функциях, использовать функции в качестве возвращаемых значений! В общем, кругом одни функции. Теперь давайте подойдём ближе к некоторым особенностями функционального программирования. Неизменность Свойством неизменности обладают значения, которые не могут быть изменены. В PHP и многих других языках их называют константами. Рекурсия Рекурсия - это один из часто используемых приёмов в функциональном программировании. При императивном подходе, для прокрутки по массивам мы можем воспользоваться циклами for или foreach, записывая текущее значение во временную переменную. Из-за принципа “неизменности”, данный подход неприемлем для функционального программирования. Предположим, что мы хотим получить сумму элементов массива (забудьте о array_sum()). При функциональном подходе, решение данной задачи будет выглядеть так: 1 <?php 2 function sum($array) { 3 if (empty($array)) 4 return 0; 5 else 6 return $array[0] + sum(array_slice($array, 1)); 7} 8 9 $total = sum(array(1, 2, 3)); // 6 Если массив пустой, то сумма элементов будет равна 0. В случае если в массиве больше элементов, мы применяем рекурсию. Чистые функции Если функция никаким образом не меняет значения переменных, которые находятся за её пределами и не осуществляет действия по вводу/выводу данных в файл, базу данных и т.д., то такую функцию можно назвать чистой. Возвращаемое значение чистых функций будет всегда одинаковым для одного и того же

Upload: solit

Post on 02-Nov-2014

148 views

Category:

Technology


1 download

DESCRIPTION

Василий Соловей, Солигорск. PHP-разработчик в в «Электронном Солигорске». «Минусы ООП на примере языка PHP». Development секция. Для разработчиков (начальный и средний уровень). 1. Что есть ООП (легкое повторение уже знакомого) 2. Лучше доверять авторитету мнения, чем мнению авторитета (во всем нужно разбираться основательно, а в ООП тем более) 3. Неизменная скупость в похвалах — верный признак посредственного ума (плюсы ООП) 4. Не все то солнышко, что блестит (основная часть доклада – минусы ООП) 5. Кто владеет информацией, тот владеет ситуацией (пояснение сути доклада: доклад не принижает и не умоляет достоинств ООП он создан расширить кругозор) «Начинать никогда не поздно!». Мотивационное выступление. На личном примере, я могу рассказать, что начинать никогда не поздно, и если есть желание – нет повода себе отказывать. 1. Путь в тысячу миль начинается с одного шага (с чего начать) 2. И на верном пути повстречаются распутья (как не сбиться с дороги начав) 3. Кто ты программист? (мой взгляд на программирование) 4. Успех – дитя настойчивости

TRANSCRIPT

Page 1: Solit 2014, Functional programming, Соловей Василий

Functional programming Важные аспекты функционального программирования

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

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

Теперь давайте подойдём ближе к некоторым особенностями функционального программирования.

Неизменность

Свойством неизменности обладают значения, которые не могут быть изменены. В PHP и многих других языках их называют константами.

Рекурсия

Рекурсия - это один из часто используемых приёмов в функциональном программировании. При императивном подходе, для прокрутки по массивам мы можем воспользоваться циклами for или foreach, записывая текущее значение во временную переменную. Из-за принципа “неизменности”, данный подход неприемлем для функционального программирования.

Предположим, что мы хотим получить сумму элементов массива (забудьте о array_sum()). При функциональном подходе, решение данной задачи будет выглядеть так:

1 <?php2 function sum($array) {3 if (empty($array))4 return 0;5 else6 return $array[0] + sum(array_slice($array, 1));7 }8 9 $total = sum(array(1, 2, 3)); // 6Если массив пустой, то сумма элементов будет равна 0. В случае если в массиве больше элементов, мы применяем рекурсию.

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

Если функция никаким образом не меняет значения переменных, которые находятся за её пределами и не осуществляет действия по вводу/выводу данных в файл, базу данных и т.д., то такую функцию можно назвать чистой.

Возвращаемое значение чистых функций будет всегда одинаковым для одного и того же

Page 2: Solit 2014, Functional programming, Соловей Василий

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

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

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

Лямбда функции

Лямбда функции (также известные, как анонимные функции) - это ничто иное, как функции без названия. Работа с подобными функциями осуществляется через переменную, которой данная функция была присвоена.

Возможность создания подобных функций есть во множестве языков. Вы наверняка уже писали их в вашем JavaScript коде, когда реализовывали функции обратного действия при работе с ajax.

1 $("#myButton").click(function () {2 // do something3 });Приведённый фрагмент кода - это ничто иное, как создание анонимной функции.

В PHP лямбда функции появились в версии 5.3:

1 <?php

2$square = function ($arg) {

3 return $arg * $arg;

4 };5 6 $value = $square(2); // 4Когда речь идёт об анонимных функциях, очень важно понимать область видимости переменных. К примеру, в JavaScript анонимные функции имеют доступ к переменным за их пределами, а в PHP - нет.

Замыкания

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

1 <?php2 $rate = .12;3

Page 3: Solit 2014, Functional programming, Соловей Василий

4$findInterest = function ($value) use ($rate) {

5 return $value * $rate;

6 };7 8 $interest = $findInterest(100);В этом случае, мы не передаём переменную как входящий параметр функции, а получаем к ней доступ, используя use.

Каррирование и частичное применение

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

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

01 <?php

02$volume = function ($length = 0, $width = 0, $height = 0) use (&$volume) {

03 $args = func_get_args();04 $numArgs = func_num_args();

05 if ($numArgs == 3) {

06 return $length * $width * $height;

07 }

08 else if ($numArgs < 3) {

09 return function() use(&$volume, $args) {10 $newArgs = array_merge($args, func_get_args());11 return call_user_func_array($volume, $newArgs);12 };13 }14 else {

15 throw new BadFunctionCallException("Too many arguments");

16 }17 };В первой проверке мы проверяем количество аргументов. Если оно равно 3, то возвращаем результат. Если изначальное количество аргументов меньше, вызываем другую функцию, которая пытается найти решение с заданными данными.

Таким образом, мы можем вычислить размер коробки, передав сначала один аргумент, а потом и другие.

Page 4: Solit 2014, Functional programming, Соловей Василий

1 <?php2 $standardVolume = $volume(10);3 4 $vol = $standardVolume(5, 5); // 250Каррирование - это специальный вид функции частичного применения, когда каждый аргумент может быть принят в отдельную функцию. Что-то типа f(x,y,z) to f(x)(y)(z). В PHP такой синтаксис невозможен, но реализовать принцип можно.

Плюсы и минусы

В использовании функционального подхода есть множество плюсов. К примеру, анонимные функции можно использовать в качестве функций обратного вызова. Как в фрэймворке Slim:

1 <?php

2$app = new \Slim\Slim();

3 $app->get("/home", function () {4 // show home page5 });В данном примере, анонимная функция запустится, когда пользователь зайдёт по адресу home.

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

Однако стоит заметить, что не все приёмы данной парадигмы можно реализовать в PHP. В качестве примера, можно привести работу с параллельными процессами.

Также не всегда можно определить сложность рекурсивной функции и её эффект на производительность кода. Иногда стоит отойти от функционального принципа.

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

Итог

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