Your SlideShare is downloading. ×
0
Функциональное программирование на Яве DevClub 26.11.2009 Andrei Solntsev
О чём это мы? Данный пптах даёт представление   о методах Функционального Программирования и их применении в ООП-языках ти...
Оглавление <ul><li>ФП для чайников </li></ul><ul><li>Основные свойства ФП </li></ul><ul><li>Примеры кода   на  Haskell </l...
Введение в ФП Вычисление -  последовательное выполнение команд, изменяющих состояние . Императивное программирование Функц...
Алгоритм На каком примере всем объясняют понятие «алгоритм»? Бутерброд!
Алгоритм бутерброда Фунцкия   createSandwich <ul><li>Возьми кусок хлеба </li></ul><ul><li>Намажь масло на хлеб </li></ul><...
Алгоритм бутерброда Что ,  если мы хотим  использовать  колбасу  вместо  сыра  ? Давайте передавать колбасу/сыр как входно...
Алгоритм бутерброда <ul><li>Возьми  низ </li></ul><ul><li>Намажь  середину  на  низ </li></ul><ul><li>Положи  верх  на  се...
Алгоритм бутерброда Что ,  если мы хотим не  намазывать  масло, а  класть  кусками? Императивное программирование :  Пробл...
Алгоритм бутерброда <ul><li>Возьми  низ </li></ul><ul><li>if   способ  = ‘ класть ’ положи   середину  на  низ   else нама...
Алгоритм бутерброда return put ( верх , action ( середина, низ ) ) Function  createSandwich ( низ ,  середина ,  верх ,  a...
Функциональный бутерброд
Основные свойства ФП Что такое Функциональное Программмирование ? <ul><li>Closures and higher order functions </li></ul><u...
<ul><li>ФП для чайников </li></ul><ul><li>Основные свойства ФП </li></ul><ul><li>Примеры кода   на  Haskell </li></ul><ul>...
Примеры кода на  Haskell <ul><li>a dd   :: I n teger -> Integer -> Integer </li></ul><ul><li>add  x y   =  x + y </li></ul...
Примеры кода на  Haskell <ul><li>a dd   :: I n teger -> Integer -> Integer </li></ul><ul><li>add  x y   =  x + y </li></ul...
<ul><li>ones   = 1 : ones  </li></ul>Примеры кода на  Haskell Бесконечные   структуры данных numsFrom n   =   n   :   nums...
Примеры кода в стиле ФП в  Java java.util.Properties Properties properties = new Properties(); properties.setProperty(“fir...
Примеры кода в стиле ФП в  Java java.lang.StringBuffer StringBuffer sb = new StringBuffer(); sb.append(“a”); sb.append(“b”...
ФП :  За и против За <ul><li>Надёжный ( reliable ) код </li></ul><ul><li>Читаемый  (readable)  код </li></ul><ul><li>Много...
Quicksort на языке Haskell <ul><li>qsort  [] = [] </li></ul><ul><li>qsort  (x:xs) =  qsort   elts_lt_x   ++ </li></ul><ul>...
Quicksort на языке C <ul><li>qsort( a, lo, hi ) int a[], hi, lo; </li></ul><ul><li>{ </li></ul><ul><li>int h, l, p, t; </l...
ФП :  За и против В языках типа  Java,  ФП хорошо подходит для  реализации бизнес-логики и обработки списков Проще придумы...
<ul><li>ФП для чайников </li></ul><ul><li>Основные свойства ФП </li></ul><ul><li>Примеры кода   на  Haskell </li></ul><ul>...
25 ый   кадр 25 ый   кадр
Бизнес-логика с помощью ФП Класс  GroomFilter List  suitableGrooms  = new ArrayList(); for (groom in allGrooms) { if ( min...
Бизнес-логика с помощью ФП Класс  GroomFilter List suitableGrooms = new ArrayList(); for (groom in allGrooms) { if ( groom...
Google collections package com.google.common.base; public interface  Predicate <T> { { /** *  Возвращает  true  или  false...
Google collections package com.google.common.base; public class  Predicates   { static <T> Predicate<T>  alwaysTrue (); st...
Google collections package com.google.common.collect; public class  Collections2   { static <E> Collection<E>  filter ( Co...
Бизнес-логика с помощью ФП Класс  GroomFilter return  Collections2.filter (allGrooms, groomChecker); List filterGrooms(Lis...
Бизнес-логика с помощью ФП Клиент  1 List suitableGrooms grooms = GroomFilter.filterGrooms(…, new Predicate<Groom>() { pub...
Применение ФП :  Фильтры Дано :  список имён женихов . Найти :  все имена, начинающиеся на  “Mr.” List  gentlemen  = new L...
Применение ФП :  Фильтры Функциональное программирование: import com.google.common.collect.Collections2; return  Collectio...
Применение ФП :  Функции Дано :  список женихов Найти :  список имён женихов List  groomsNames  = new ArrayList(); for (It...
Применение ФП :  Функции import com.google.common.collect.Collections2; return  Collections2. transform(  allGrooms , new ...
Google collections GC  позволяет сделать и более элегантные конструкции boolean  result  =  and( not( in(list1) ), in(list...
Эпи log 4 j <ul><li>В следующий раз, прежде чем написать  FOR  или  IF,  задумайтесь!  </li></ul>Скачайте себе  Haskell  и...
Upcoming SlideShare
Loading in...5
×

Functional Programming Dev Club 2009 - final

1,125

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,125
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
14
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "Functional Programming Dev Club 2009 - final"

  1. 1. Функциональное программирование на Яве DevClub 26.11.2009 Andrei Solntsev
  2. 2. О чём это мы? Данный пптах даёт представление о методах Функционального Программирования и их применении в ООП-языках типа Java Кое-где придётся подумать!
  3. 3. Оглавление <ul><li>ФП для чайников </li></ul><ul><li>Основные свойства ФП </li></ul><ul><li>Примеры кода на Haskell </li></ul><ul><li>Примеры кода на Java </li></ul><ul><li>ФП для бизнес-логики </li></ul>
  4. 4. Введение в ФП Вычисление - последовательное выполнение команд, изменяющих состояние . Императивное программирование Функциональное программирование Вычисление - нахождение значения выражения КАК Выражения образованы из функций для комбинации базовых значений и других функций Программа состоит из нескольких последовательных команд . ЧТО против
  5. 5. Алгоритм На каком примере всем объясняют понятие «алгоритм»? Бутерброд!
  6. 6. Алгоритм бутерброда Фунцкия createSandwich <ul><li>Возьми кусок хлеба </li></ul><ul><li>Намажь масло на хлеб </li></ul><ul><li>Положи сыр на масло </li></ul><ul><li>return result </li></ul>Императивный стиль return Функциональный стиль положи ( сыр , намажь ( масло , хлеб ) )
  7. 7. Алгоритм бутерброда Что , если мы хотим использовать колбасу вместо сыра ? Давайте передавать колбасу/сыр как входной параметр функции Нет проблем !
  8. 8. Алгоритм бутерброда <ul><li>Возьми низ </li></ul><ul><li>Намажь середину на низ </li></ul><ul><li>Положи верх на середину </li></ul><ul><li>return result </li></ul>Function createSandwich ( низ , середина , верх ) return положи ( верх , намажь ( середина , низ ) ) Function createSandwich ( низ , середина , верх ) Нет проблем ! хлеб масло колбаса
  9. 9. Алгоритм бутерброда Что , если мы хотим не намазывать масло, а класть кусками? Императивное программирование : Проблема ! Функциональное программирование : по-прежнему нет проблем
  10. 10. Алгоритм бутерброда <ul><li>Возьми низ </li></ul><ul><li>if способ = ‘ класть ’ положи середину на низ else намажь середину на низ end if </li></ul><ul><li>Положи верх на середину </li></ul><ul><li>return result </li></ul>Function createSandwich ( низ , середина , верх , способ ) хлеб масло колбаса класть Альтернативный вариант : создать 2 разные функции  Дублирование кода Императивное программирование : Проблема ! Больше способов – больше IF’ ов
  11. 11. Алгоритм бутерброда return put ( верх , action ( середина, низ ) ) Function createSandwich ( низ , середина , верх , action ) хлеб масло колбаса класть Action – это функция с двумя аргументами <ul><li>Намазывать </li></ul><ul><li>класть </li></ul><ul><li>… </li></ul>createSandwich – функция более высокого порядка ( higher-order function ), которая принимает другую функцию как аргумент Функциональное программирование : нет проблем
  12. 12. Функциональный бутерброд
  13. 13. Основные свойства ФП Что такое Функциональное Программмирование ? <ul><li>Closures and higher order functions </li></ul><ul><li>Lazy evaluation </li></ul><ul><li>Recursion as a mechanism for control flow </li></ul><ul><li>Enforcement of referential transparency </li></ul><ul><li>No side-effects </li></ul><ul><li>Lambda calculus </li></ul>Функциональные языки <ul><li>Lisp (AutoCad) </li></ul><ul><li>Haskell, Scheme, Logo </li></ul><ul><li>XSLT </li></ul>Там, где традиционная императивная программа использует цикл для прохождения по списку, функциональный стиль использует функцию высокого порядка map, которая принимает другую функцию и список, применяет эту функцию к каждому элементу списка и возвращает список из результатов. <ul><li>Scala, LambdaJ, Clojure </li></ul>
  14. 14. <ul><li>ФП для чайников </li></ul><ul><li>Основные свойства ФП </li></ul><ul><li>Примеры кода на Haskell </li></ul><ul><li>Примеры кода на Java </li></ul><ul><li>ФП для бизнес-логики </li></ul>
  15. 15. Примеры кода на Haskell <ul><li>a dd :: I n teger -> Integer -> Integer </li></ul><ul><li>add  x y =  x + y </li></ul>functions add  1   2 =   3 add  6   9 =   1 5 add  1 =   ? Ух ты ! add  1 = функция типа Integer -> Integer Currying http://en.wikipedia.org/wiki/Currying
  16. 16. Примеры кода на Haskell <ul><li>a dd :: I n teger -> Integer -> Integer </li></ul><ul><li>add  x y =  x + y </li></ul>functions inc :: Integer -> Integer inc = add 1 map :: (a->b) -> [a] -> [b] map  f  []       =  [] map  f (x:xs)    =  f x : map f xs Uncurried function F unction can be returned as a value ! Higher-order function curried function
  17. 17. <ul><li>ones = 1 : ones </li></ul>Примеры кода на Haskell Бесконечные структуры данных numsFrom n = n : numsFrom (n+1) squares = map (^2) (numsfrom 0) take 5 squares => [0,1,4,9,16] Это выражение вычисляется за конечное число шагов Потому что Lazy Evaluation!
  18. 18. Примеры кода в стиле ФП в Java java.util.Properties Properties properties = new Properties(); properties.setProperty(“firstName&quot;, groom.getFirstName()); properties.setProperty(“lastName&quot;, groom.getLastName()); properties.setProperty(“salary&quot;, groom.getSalary()); return parameters; return Императивный Функциональный return new Properties() .setProperty(“firstName&quot;, groom.getFirstName()) .setProperty(“lastName&quot;, groom.getLastName()) .setProperty(“salary&quot;, groom.getSalary()); <ul><li>Плюсы? </li></ul><ul><li>Минусы? </li></ul>йа баго нихт баго
  19. 19. Примеры кода в стиле ФП в Java 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(); Императивный Функциональный <ul><li>Плюсы? </li></ul><ul><li>Минусы ? </li></ul>
  20. 20. ФП : За и против За <ul><li>Надёжный ( reliable ) код </li></ul><ul><li>Читаемый (readable) код </li></ul><ul><li>Многократно используемый ( Reusable ) код </li></ul><ul><li>Неестественный для человека </li></ul><ul><li>Неестественный для компьютера </li></ul><ul><li>Отсутствие контроля над процессом </li></ul><ul><li>Производительность </li></ul>Против Пример : алгоритм быстрой сортировки ( Quick Sort )
  21. 21. Quicksort на языке Haskell <ul><li>qsort [] = [] </li></ul><ul><li>qsort (x:xs) = qsort elts_lt_x ++ </li></ul><ul><li>[x] ++ </li></ul><ul><li>qsort elts_greq_x </li></ul><ul><li>where </li></ul><ul><li>elts_lt_x = [y | y <- xs, y < x] </li></ul><ul><li>elts_greq_x = [y | y <- xs, y >= x] </li></ul>Сравните с Quicksort на языке C:
  22. 22. Quicksort на языке C <ul><li>qsort( a, lo, hi ) int a[], hi, lo; </li></ul><ul><li>{ </li></ul><ul><li>int h, l, p, t; </li></ul><ul><li>if (lo < hi) { </li></ul><ul><li>l = lo; h = hi; p = a[hi]; </li></ul><ul><li>do { </li></ul><ul><li>while ((l < h) && (a[l] <= p)) </li></ul><ul><li>l = l+1; </li></ul><ul><li>while ((h > l) && (a[h] >= p)) </li></ul><ul><li>h = h-1; </li></ul><ul><li>if (l < h) { </li></ul><ul><li>t = a[l]; a[l] = a[h]; a[h] = t; </li></ul><ul><li>} </li></ul><ul><li>} while (l < h); </li></ul><ul><li>t = a[l]; a[l] = a[hi]; a[hi] = t; </li></ul><ul><li>qsort( a, lo, l-1 ); </li></ul><ul><li>qsort( a, l+1, hi ); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
  23. 23. ФП : За и против В языках типа Java, ФП хорошо подходит для реализации бизнес-логики и обработки списков Проще придумывать, писать и поддерживать ПО, но программист имеет меньше контроля над тем, что происходит во время выполнения программы. За Вывод
  24. 24. <ul><li>ФП для чайников </li></ul><ul><li>Основные свойства ФП </li></ul><ul><li>Примеры кода на Haskell </li></ul><ul><li>Примеры кода на Java </li></ul><ul><li>ФП для бизнес-логики </li></ul>
  25. 25. 25 ый кадр 25 ый кадр
  26. 26. Бизнес-логика с помощью ФП Класс 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 , то возраст проверять не нужно Отфильтровывает женихов Как сделать более сложные проверки?
  27. 27. Бизнес-логика с помощью ФП Класс GroomFilter List suitableGrooms = new ArrayList(); for (groom in allGrooms) { if ( groomChecker .apply(groom)) suitableGrooms.add(groom); } return suitableGrooms; List filterGrooms(List allGrooms, Predicate groomChecker ) Передаём функцию как параметр
  28. 28. Google collections package com.google.common.base; public interface Predicate <T> { { /** * Возвращает true или false для данного объекта */ boolean apply (T input); } http://bwinterberg.blogspot.com/2009/09/introduction-to-google-collections.html http://code.google.com/p/google-collections/
  29. 29. Google collections 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); … }
  30. 30. 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 ) }
  31. 31. Бизнес-логика с помощью ФП Класс GroomFilter return Collections2.filter (allGrooms, groomChecker); List filterGrooms(List allGrooms, Predicate groomChecker ) Функция filterGrooms становится ещё проще
  32. 32. Бизнес-логика с помощью ФП Клиент 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
  33. 33. Применение ФП : Фильтры Дано : список имён женихов . Найти : все имена, начинающиеся на “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 ; Императивное программирование:
  34. 34. Применение ФП : Фильтры Функциональное программирование: import com.google.common.collect.Collections2; return Collections2 . filter( allGrooms, StringPredicates.startsWith( “Mr.” ) ) ; Дано : список имён женихов . Найти : все имена, начинающиеся на “Mr.”
  35. 35. Применение ФП : Функции Дано : список женихов Найти : список имён женихов List groomsNames = new ArrayList(); for (Iterator it = allGrooms .iterator(); it.hasNext(); ) { Groom groom = (Groom) it.next(); groomsNames .add(groom.getName()); } return groomsNames ; Императивное программирование
  36. 36. Применение ФП : Функции import com.google.common.collect.Collections2; return Collections2. transform( allGrooms , new Function<Groom, String> () { public String apply(Groom groom) { return groom.getName(); } } ) ; Функциональное программирование Дано : список женихов Найти : список имён женихов На первый взгляд, не столь красиво, но может быть вынесено в отдельный класс и многократно использовано!
  37. 37. Google collections GC позволяет сделать и более элегантные конструкции boolean result = and( not( in(list1) ), in(list2), in(list3)).apply(&quot;1&quot;); Collection names = Joiner.on(&quot;; &quot;).useForNull(&quot;B000&quot;).join(filtered);
  38. 38. Эпи log 4 j <ul><li>В следующий раз, прежде чем написать FOR или IF, задумайтесь! </li></ul>Скачайте себе Haskell и поиграйтесь на досуге. Если это не убьёт ваш мозг, то сделает его сильнее.
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×