Top Banner
Функциональное программирование на Яве DevClub 26.11.2009 Andrei Solntsev
38

Functional Programming Dev Club 2009 - final

Jan 25, 2015

Download

Technology

Andrei Solntsev

 
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Functional Programming Dev Club 2009 - final

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

на ЯвеDevClub

26.11.2009

Andrei Solntsev

Page 2: Functional Programming Dev Club 2009 - final

О чём это мы?

Данный пптахдаёт представление

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

их применениив ООП-языках типа Java

Кое-где придётся подумать!

Page 3: Functional Programming Dev Club 2009 - final

Оглавление

ФП для чайников Основные свойства ФП Примеры кода на Haskell Примеры кода на Java ФП для бизнес-логики

Page 4: Functional Programming Dev Club 2009 - final

Введение в ФП

Вычисление - последовательное выполнение команд, изменяющих состояние.

Императивное программирование

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

Вычисление -нахождение значения выражения

КАК

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

Программа состоит из нескольких последовательных команд.

ЧТО

против

Page 5: Functional Programming Dev Club 2009 - final

Алгоритм

На каком примере всем объясняют понятие «алгоритм»?

Бутерброд!

Page 6: Functional Programming Dev Club 2009 - final

Алгоритм бутерброда

Фунцкия createSandwich

1. Возьми кусок хлеба2. Намажь масло на хлеб3. Положи сыр на масло4. return result

Императивный стиль

return

Функциональный стиль

положи(сыр,намажь(масло, хлеб) )

Page 7: Functional Programming Dev Club 2009 - final

Что, если мы хотим использовать колбасу вместо сыра ?

Давайте передавать колбасу/сыр как входной параметр функции

Нет проблем!

Алгоритм бутерброда

Page 8: Functional Programming Dev Club 2009 - final

1. Возьми низ2. Намажь середину на низ3. Положи верх на середину4. return result

Function createSandwich (низ, середина, верх)

return положи(верх,намажь(середина, низ) )

Function createSandwich (низ, середина, верх)

Нет проблем!

хлеб масло колбаса

Алгоритм бутерброда

Page 9: Functional Programming Dev Club 2009 - final

Что, если мы хотим не намазывать масло, а класть кусками?

Императивное программирование: Проблема!

Функциональное программирование: по-прежнему нет проблем

Алгоритм бутерброда

Page 10: Functional Programming Dev Club 2009 - final

1. Возьми низ2. if способ = ‘класть’

положи середину на низ else

намажь середину на низ end if

3. Положи верх на середину4. return result

Function createSandwich (низ, середина, верх, способ)

хлеб масло колбаса класть

Альтернативный вариант: создать 2 разные функции Дублирование кода

Алгоритм бутерброда

Императивное программирование: Проблема!

Больше способов – больше IF’ов

Page 11: Functional Programming Dev Club 2009 - final

return put ( верх,action(середина, низ) )

Function createSandwich (низ, середина, верх, action)

хлеб масло колбаса класть

Action – это функция с двумя аргументами

• Намазывать• класть• …

createSandwich – функция более высокого порядка (higher-order function), которая принимает другую функцию как аргумент

Алгоритм бутерброда

Функциональное программирование: нет проблем

Page 12: Functional Programming Dev Club 2009 - final

Функциональный бутерброд

Page 13: Functional Programming Dev Club 2009 - final

Основные свойства ФП

Что такое Функциональное Программмирование?

• Closures and higher order functions

• Lazy evaluation

• Recursion as a mechanism for control flow

• Enforcement of referential transparency

• No side-effects

• Lambda calculus

Функциональные языки• Lisp (AutoCad)

• Haskell, Scheme, Logo

• XSLT

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

• Scala, LambdaJ, Clojure

Page 14: Functional Programming Dev Club 2009 - final

ФП для чайников Основные свойства ФП Примеры кода на Haskell Примеры кода на Java ФП для бизнес-логики

Page 15: Functional Programming Dev Club 2009 - final

Примеры кода на Haskell

add :: Integer -> Integer -> Integeradd x y =  x + y

functions

add 1 2 = 3add 6 9 = 15

add 1 = ?

Ух ты!add 1 = функция типа Integer -> Integer

Curryinghttp://en.wikipedia.org/wiki/Currying

Page 16: Functional Programming Dev Club 2009 - final

Примеры кода на Haskell

add :: Integer -> Integer -> Integeradd x y =  x + y

functions

inc :: Integer -> Integerinc = add 1

map :: (a->b) -> [a] -> [b]map f  []       =  []map f (x:xs)    =  f x : map f xs

Uncurriedfunction

Function can bereturned as a value !

Higher-orderfunction

curriedfunction

Page 17: Functional Programming Dev Club 2009 - final

ones = 1 : ones

Бесконечные структуры данных

numsFrom n = n : numsFrom (n+1)

squares = map (^2) (numsfrom 0)

take 5 squares => [0,1,4,9,16]

Примеры кода на Haskell

Это выражение вычисляется за конечное число шагов

Потому что Lazy Evaluation!

Page 18: Functional Programming Dev Club 2009 - final

Примеры кода в стиле ФП в Java

java.util.Properties

Properties properties = new Properties();properties.setProperty(“firstName", groom.getFirstName());properties.setProperty(“lastName", groom.getLastName());properties.setProperty(“salary", groom.getSalary());return parameters;

return

Императивный

Функциональный

return new Properties() .setProperty(“firstName", groom.getFirstName()) .setProperty(“lastName", groom.getLastName()) .setProperty(“salary", groom.getSalary());• Плюсы?

• Минусы?

йа баго

нихт баго

Page 19: Functional Programming Dev Club 2009 - final

java.lang.StringBuffer

StringBuffer sb = new StringBuffer();sb.append(“a”);sb.append(“b”);sb.append(“c”);return sb.toString();

return new StringBuffer() .append(“a”); .append(“b”); .append(“c”) .toString();

Императивный

Функциональный

• Плюсы? • Минусы?

Примеры кода в стиле ФП в Java

Page 20: Functional Programming Dev Club 2009 - final

ФП: За и против

За

• Надёжный (reliable) код• Читаемый (readable) код• Многократно используемый (Reusable) код

• Неестественный для человека• Неестественный для компьютера• Отсутствие контроля над процессом• Производительность

Против

Пример: алгоритм быстрой сортировки (Quick Sort)

Page 21: Functional Programming Dev Club 2009 - final

Quicksort на языке Haskell

qsort [] = []

qsort (x:xs) = qsort elts_lt_x ++

[x] ++

qsort elts_greq_x

where

elts_lt_x = [y | y <- xs, y < x]

elts_greq_x = [y | y <- xs, y >= x]

Сравните с Quicksort на языке C:

Page 22: Functional Programming Dev Club 2009 - final

Quicksort на языке C

qsort( a, lo, hi ) int a[], hi, lo;{

int h, l, p, t;if (lo < hi) {

l = lo; h = hi; p = a[hi];do {

while ((l < h) && (a[l] <= p))l = l+1;

while ((h > l) && (a[h] >= p))h = h-1;

if (l < h) {t = a[l]; a[l] = a[h]; a[h] = t;

}} while (l < h);

t = a[l]; a[l] = a[hi]; a[hi] = t;qsort( a, lo, l-1 );qsort( a, l+1, hi );

}}

Page 23: Functional Programming Dev Club 2009 - final

В языках типа Java, ФП хорошо подходит для реализации бизнес-логики и обработки списков

Проще придумывать, писать и поддерживать ПО,но программист имеет меньше контроля над тем, что происходит во время выполнения программы.

ФП: За и против

За

Вывод

Page 24: Functional Programming Dev Club 2009 - final

ФП для чайников Основные свойства ФП Примеры кода на Haskell Примеры кода на Java ФП для бизнес-логики

Page 25: Functional Programming Dev Club 2009 - final

25ый кадр

25ый кадр

Page 26: Functional Programming Dev Club 2009 - final

Бизнес-логика с помощью ФП

Класс GroomFilter

List suitableGrooms = new ArrayList();

for (groom in allGrooms){ if (minAge > -1 && groom.getAge() < minAge)

continue;

if (maxAge > -1 && groom.getAge() > maxAge)continue;

suitableGrooms.add(groom);}

return suitableGrooms;

List filterGrooms(List allGrooms, int minAge, int maxAge)

Если age = -1, то возраст проверять не нужно

Отфильтровывает женихов

Как сделать более сложные проверки?

Page 27: Functional Programming Dev Club 2009 - final

Класс GroomFilter

List suitableGrooms = new ArrayList();

for (groom in allGrooms){ if (groomChecker.apply(groom))

suitableGrooms.add(groom);}

return suitableGrooms;

List filterGrooms(List allGrooms, Predicate groomChecker)

Передаём функцию как параметр

Бизнес-логика с помощью ФП

Page 28: Functional Programming Dev Club 2009 - final

package com.google.common.base;

public interface Predicate<T> {{ /** * Возвращает true или false для данного объекта */ boolean apply(T input);}

Google collections

http://bwinterberg.blogspot.com/2009/09/introduction-to-google-collections.htmlhttp://code.google.com/p/google-collections/

Page 29: Functional Programming Dev Club 2009 - final

package com.google.common.base;

public class Predicates { static <T> Predicate<T> alwaysTrue(); static <T> Predicate<T> alwaysFalse();

static <T> Predicate<T> isNull(); static <T> Predicate<T> notNull();

static <T> Predicate<T> not(Predicate<T> predicate); static <T> Predicate<T> and(Predicate<? super T>... components);

…}

Google collections

Page 30: Functional Programming Dev Club 2009 - final

Google collections

package com.google.common.collect;

public class Collections2 { static <E> Collection<E> filter(

Collection<E> unfiltered, Predicate<? super E> predicate)

static <F, T> Collection<T> transform(Collection<F> fromCollection, Function<? super F, T> function)

}

Page 31: Functional Programming Dev Club 2009 - final

Класс GroomFilter

return Collections2.filter(allGrooms, groomChecker);

List filterGrooms(List allGrooms, Predicate groomChecker)

Функция filterGrooms становится ещё проще

Бизнес-логика с помощью ФП

Page 32: Functional Programming Dev Club 2009 - final

Клиент 1

List suitableGrooms grooms = GroomFilter.filterGrooms(…, new Predicate<Groom>() {

public boolean apply(Groom groom){ return groom.getAge() > 23;}

});

Клиент 2

List suitableGrooms = GroomFilter.filterGrooms(…,Predicates.alwaysTrue());

Closure – Объект, представляющий функцию

Анонимные классычасто используются в качестве closures

Бизнес-логика с помощью ФП

Page 33: Functional Programming Dev Club 2009 - final

Дано: список имён женихов.Найти: все имена, начинающиеся на “Mr.”

List gentlemen = new LinkedList();

for (Iterator it = groomsNames.iterator(); it.hasNext(); ){ String name = (String) it.next(); if (name != null &&

name.startsWith(“Mr.”)) {

gentlemen.add(name); }}

return gentlemen;

Императивное программирование:

Применение ФП: Фильтры

Page 34: Functional Programming Dev Club 2009 - final

Функциональное программирование:

import com.google.common.collect.Collections2;

return Collections2.filter(allGrooms,StringPredicates.startsWith(“Mr.”));

Дано: список имён женихов.Найти: все имена, начинающиеся на “Mr.”

Применение ФП: Фильтры

Page 35: Functional Programming Dev Club 2009 - final

Дано: список жениховНайти: список имён женихов

List groomsNames = new ArrayList();

for (Iterator it = allGrooms.iterator(); it.hasNext(); ){ Groom groom = (Groom) it.next(); groomsNames.add(groom.getName());}

return groomsNames;

Императивное программирование

Применение ФП: Функции

Page 36: Functional Programming Dev Club 2009 - final

import com.google.common.collect.Collections2;

return Collections2.transform( allGrooms,new Function<Groom, String>(){ public String apply(Groom groom) {

return groom.getName(); }});

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

Применение ФП: Функции

Дано: список жениховНайти: список имён женихов

На первый взгляд, не столь красиво, номожет быть вынесено в отдельный класс и многократно использовано!

Page 37: Functional Programming Dev Club 2009 - final

Google collections

GC позволяет сделать и более элегантные конструкции

boolean result = and( not( in(list1) ), in(list2), in(list3)).apply("1");

Collection names = Joiner.on("; ").useForNull("B000").join(filtered);

Page 38: Functional Programming Dev Club 2009 - final

Эпиlog4j

В следующий раз, прежде чем написать FOR или IF, задумайтесь!

Скачайте себе Haskell и поиграйтесь на досуге. Если это не убьёт ваш мозг, то сделает его сильнее.