SlideShare a Scribd company logo
1 of 49
А нам-то зачем
функциональное
программирование?
Вагиф Абилов
Miles Norway
http://www.codeproject.com
A short poem by Afanasy Fet (1850) without a single verb
let neighbours (x, y) =
[ for i in x-1..x+1 do
for j in y-1..y+1 do
if not (i = x && j = y) then yield (i,j) ]
let isAlive population cell =
population
|> List.exists ((=) cell)
let aliveNeighbours population cell =
neighbours cell
|> List.filter (isAlive population)
let survives population cell =
aliveNeighbours population cell
|> List.length
|> fun x -> x >= 2 && x <= 3
let reproducible population cell =
aliveNeighbours population cell
|> List.length = 3
let allDeadNeighbours population =
population
|> List.collect neighbours
|> Set.ofList |> Set.toList
|> List.filter (not << isAlive population)
let nextGeneration population =
List.append
(population
|> List.filter (survives population))
(allDeadNeighbours population
|> List.filter (reproducible population))
Note use of colors: the only word in white is ”population". No variables!
let isAlive population cell =
population
|> List.exists ((=) cell)
let aliveNeighbours population cell =
neighbours cell
|> List.filter (isAlive population)
let survives population cell =
aliveNeighbours population cell
|> List.length
|> fun x -> x >= 2 && x <= 3
let reproducible population cell =
aliveNeighbours population cell
|> List.length = 3
let allDeadNeighbours population =
population
|> List.collect neighbours
|> Set.ofList |> Set.toList
|> List.filter (not << isAlive population)
let nextGeneration population =
List.append
(population
|> List.filter
(survives population))
(allDeadNeighbours population
|> List.filter
(reproducible population))
let neighbours (x, y) =
[ for i in x-1..x+1 do
for j in y-1..y+1 do
if not (i = x && j = y) then yield (i,j) ]
let neighbours (x, y, z) =
[ for i in x-1..x+1 do
for j in y-1..y+1 do
for k in z-1..z+1 do
if not (i = x && j = y && k = z) then yield (i,j,k) ]
type Color = Red | Green | Blue | White | Gray
| Black | Orange | Yellow | Brown
let neighbours color =
match color with
| Red -> [Red; Orange; Brown]
| Green -> [Green; Blue; Yellow]
| Blue -> [Blue; Green]
| White -> [White; Gray]
| Black -> [Black; Gray]
| Gray -> [Gray; Black; White]
| Orange -> [Orange; Red; Yellow]
| Yellow -> [Yellow; Orange; Green]
| Brown -> [Brown; Red]
let isAlive population cell =
population
|> List.exists ((=) cell)
let aliveNeighbours population cell =
neighbours cell
|> List.filter (isAlive population)
let survives population cell =
aliveNeighbours population cell
|> List.length
|> fun x -> x >= 2 && x <= 3
let reproducible population cell =
aliveNeighbours population cell
|> List.length = 3
let allDeadNeighbours population =
population
|> List.collect neighbours
|> Set.ofList |> Set.toList
|> List.filter (not << isAlive population)
let nextGeneration population =
List.append
(population
|> List.filter
(survives population))
(allDeadNeighbours population
|> List.filter
(reproducible population))
// Sequential solution
let nextGeneration population =
List.append
(population
|> List.filter (survives population))
(allDeadNeighbours population
|> List.filter (reproducible population))
// Parallel solution
let nextGeneration population =
seq {
yield (population
|> PList.filter (survives population))
yield (allDeadNeighbours population
|> PList.filter (reproducible population))
}
|> PSeq.toList
http://bit.ly/1MI0kLd
http://bit.ly/1GTFpRw
type CardType = VISA | MasterCard | AmEx | Diners | Domestic
type CardNumber = string
type PaymentMethod =
| Cash
| Cheque of int
| Card of CardType * CardNumber
let calculateTips sum paymentMethod =
match paymentMethod with
| Cash -> sum * 0.05
| Cheque _ -> sum * 0.20
| Card (cardType, _) when cardType = Domestic -> sum * 0.10
| Card (_, _) -> sum * 0.15
Term "Railway Oriented
Programming" coined by
ScottWlaschin
Source: http://bit.ly/1CqGyAN
Product
|> placeInShoppingCart
|> proceedToCheckout
|> selectShipmentMethod
|> selectPaymentMethod
|> authorizePayment
let ``Block should not change``() =
let population = [(1,1); (1,2); (2,1); (2,2)]
population
|> nextGeneration
|> should equal population
Scenario
Given
And 3
When
Then 4
let [<Given>] ``a customer buys a black jumper`` () = ()
let [<Given>] ``I have (.*) black jumpers left in stock`` (n : int) =
stockItem <- { stockItem with Count = n }
let [<When>] ``he returns the jumper for a refund`` () =
stockItem <- { stockItem with Count = stockItem.Count + 1 }
let [<Then>] ``I should have (.*) black jumpers in stock`` (n : int) =
stockItem.Count |> should equal n
абилов   а зачем нам функциональное программирование
абилов   а зачем нам функциональное программирование
абилов   а зачем нам функциональное программирование
абилов   а зачем нам функциональное программирование
абилов   а зачем нам функциональное программирование
абилов   а зачем нам функциональное программирование
абилов   а зачем нам функциональное программирование
абилов   а зачем нам функциональное программирование
абилов   а зачем нам функциональное программирование

More Related Content

Similar to абилов а зачем нам функциональное программирование

Five Languages in a Moment
Five Languages in a MomentFive Languages in a Moment
Five Languages in a MomentSergio Gil
 
Presentation R basic teaching module
Presentation R basic teaching modulePresentation R basic teaching module
Presentation R basic teaching moduleSander Timmer
 
introductionpart1-160906115340 (1).pptx
introductionpart1-160906115340 (1).pptxintroductionpart1-160906115340 (1).pptx
introductionpart1-160906115340 (1).pptxAsthaChaurasia4
 
Puppet Language 4.0 - PuppetConf 2014
Puppet Language 4.0 - PuppetConf 2014Puppet Language 4.0 - PuppetConf 2014
Puppet Language 4.0 - PuppetConf 2014Puppet
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patternsleague
 
Seminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov Vyacheslav
Seminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov VyacheslavSeminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov Vyacheslav
Seminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov VyacheslavVyacheslav Arbuzov
 
Артём Акуляков - F# for Data Analysis
Артём Акуляков - F# for Data AnalysisАртём Акуляков - F# for Data Analysis
Артём Акуляков - F# for Data AnalysisSpbDotNet Community
 
[1062BPY12001] Data analysis with R / week 3
[1062BPY12001] Data analysis with R / week 3[1062BPY12001] Data analysis with R / week 3
[1062BPY12001] Data analysis with R / week 3Kevin Chun-Hsien Hsu
 

Similar to абилов а зачем нам функциональное программирование (9)

Five Languages in a Moment
Five Languages in a MomentFive Languages in a Moment
Five Languages in a Moment
 
Presentation R basic teaching module
Presentation R basic teaching modulePresentation R basic teaching module
Presentation R basic teaching module
 
FYP Final Presentation
FYP Final PresentationFYP Final Presentation
FYP Final Presentation
 
introductionpart1-160906115340 (1).pptx
introductionpart1-160906115340 (1).pptxintroductionpart1-160906115340 (1).pptx
introductionpart1-160906115340 (1).pptx
 
Puppet Language 4.0 - PuppetConf 2014
Puppet Language 4.0 - PuppetConf 2014Puppet Language 4.0 - PuppetConf 2014
Puppet Language 4.0 - PuppetConf 2014
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patterns
 
Seminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov Vyacheslav
Seminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov VyacheslavSeminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov Vyacheslav
Seminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov Vyacheslav
 
Артём Акуляков - F# for Data Analysis
Артём Акуляков - F# for Data AnalysisАртём Акуляков - F# for Data Analysis
Артём Акуляков - F# for Data Analysis
 
[1062BPY12001] Data analysis with R / week 3
[1062BPY12001] Data analysis with R / week 3[1062BPY12001] Data analysis with R / week 3
[1062BPY12001] Data analysis with R / week 3
 

More from Magneta AI

From outsource to productsource!
From outsource to productsource!From outsource to productsource!
From outsource to productsource!Magneta AI
 
BDD test structure
BDD test structureBDD test structure
BDD test structureMagneta AI
 
AgileCamp15. Процессный трек
AgileCamp15. Процессный трекAgileCamp15. Процессный трек
AgileCamp15. Процессный трекMagneta AI
 
Как создать концепцию продукта в виде Lean Canvas
Как создать концепцию продукта в виде Lean CanvasКак создать концепцию продукта в виде Lean Canvas
Как создать концепцию продукта в виде Lean CanvasMagneta AI
 
Эффективные ретроспективы
Эффективные ретроспективыЭффективные ретроспективы
Эффективные ретроспективыMagneta AI
 
зотин Scrum, kanban, что дальше. история nokia
зотин   Scrum, kanban, что дальше. история nokiaзотин   Scrum, kanban, что дальше. история nokia
зотин Scrum, kanban, что дальше. история nokiaMagneta AI
 
павлов все, что вы хотели знать о юнит тестах, но боялись спросить
павлов   все, что вы хотели знать о юнит тестах, но боялись спроситьпавлов   все, что вы хотели знать о юнит тестах, но боялись спросить
павлов все, что вы хотели знать о юнит тестах, но боялись спроситьMagneta AI
 
тучин как внедрить Agile, чтобы никто не заметил
тучин   как внедрить Agile, чтобы никто не заметилтучин   как внедрить Agile, чтобы никто не заметил
тучин как внедрить Agile, чтобы никто не заметилMagneta AI
 
ткаченко качество без этапа тестирования
ткаченко   качество без этапа тестированияткаченко   качество без этапа тестирования
ткаченко качество без этапа тестированияMagneta AI
 
сенькова разное ретро для разных команд (как провести ретро для новичков, с...
сенькова   разное ретро для разных команд (как провести ретро для новичков, с...сенькова   разное ретро для разных команд (как провести ретро для новичков, с...
сенькова разное ретро для разных команд (как провести ретро для новичков, с...Magneta AI
 
мациевский путь самурая. уволить нельзя оставить
мациевский   путь самурая. уволить нельзя оставитьмациевский   путь самурая. уволить нельзя оставить
мациевский путь самурая. уволить нельзя оставитьMagneta AI
 
лустин статические анализаторы систем 1с ad2015
лустин   статические анализаторы систем 1с ad2015лустин   статические анализаторы систем 1с ad2015
лустин статические анализаторы систем 1с ad2015Magneta AI
 
лосев контрольные карты шухарта в анализе деятельности Scrum команд
лосев   контрольные карты шухарта в анализе деятельности Scrum командлосев   контрольные карты шухарта в анализе деятельности Scrum команд
лосев контрольные карты шухарта в анализе деятельности Scrum командMagneta AI
 
корецкий как мы улучшили экспертную оценку проектов
корецкий   как мы улучшили экспертную оценку проектовкорецкий   как мы улучшили экспертную оценку проектов
корецкий как мы улучшили экспертную оценку проектовMagneta AI
 
зиновьева повышение эффективности команды. ретроспектива как инструмент
зиновьева   повышение эффективности команды. ретроспектива как инструментзиновьева   повышение эффективности команды. ретроспектива как инструмент
зиновьева повышение эффективности команды. ретроспектива как инструментMagneta AI
 
виноградова внедрение изменений без длинных документов, долгих согласований...
виноградова   внедрение изменений без длинных документов, долгих согласований...виноградова   внедрение изменений без длинных документов, долгих согласований...
виноградова внедрение изменений без длинных документов, долгих согласований...Magneta AI
 
верещак. построение культуры Dev ops. v0.5 copy
верещак. построение  культуры Dev ops. v0.5 copyверещак. построение  культуры Dev ops. v0.5 copy
верещак. построение культуры Dev ops. v0.5 copyMagneta AI
 
бородин об эмпирической разработке
бородин   об эмпирической разработкебородин   об эмпирической разработке
бородин об эмпирической разработкеMagneta AI
 
богуславский Agile days непрерывное качество в непрерывной разработке
богуславский   Agile days непрерывное качество в непрерывной разработкебогуславский   Agile days непрерывное качество в непрерывной разработке
богуславский Agile days непрерывное качество в непрерывной разработкеMagneta AI
 
атлыгина чеклисты для всех-всех-всех
атлыгина   чеклисты для всех-всех-всехатлыгина   чеклисты для всех-всех-всех
атлыгина чеклисты для всех-всех-всехMagneta AI
 

More from Magneta AI (20)

From outsource to productsource!
From outsource to productsource!From outsource to productsource!
From outsource to productsource!
 
BDD test structure
BDD test structureBDD test structure
BDD test structure
 
AgileCamp15. Процессный трек
AgileCamp15. Процессный трекAgileCamp15. Процессный трек
AgileCamp15. Процессный трек
 
Как создать концепцию продукта в виде Lean Canvas
Как создать концепцию продукта в виде Lean CanvasКак создать концепцию продукта в виде Lean Canvas
Как создать концепцию продукта в виде Lean Canvas
 
Эффективные ретроспективы
Эффективные ретроспективыЭффективные ретроспективы
Эффективные ретроспективы
 
зотин Scrum, kanban, что дальше. история nokia
зотин   Scrum, kanban, что дальше. история nokiaзотин   Scrum, kanban, что дальше. история nokia
зотин Scrum, kanban, что дальше. история nokia
 
павлов все, что вы хотели знать о юнит тестах, но боялись спросить
павлов   все, что вы хотели знать о юнит тестах, но боялись спроситьпавлов   все, что вы хотели знать о юнит тестах, но боялись спросить
павлов все, что вы хотели знать о юнит тестах, но боялись спросить
 
тучин как внедрить Agile, чтобы никто не заметил
тучин   как внедрить Agile, чтобы никто не заметилтучин   как внедрить Agile, чтобы никто не заметил
тучин как внедрить Agile, чтобы никто не заметил
 
ткаченко качество без этапа тестирования
ткаченко   качество без этапа тестированияткаченко   качество без этапа тестирования
ткаченко качество без этапа тестирования
 
сенькова разное ретро для разных команд (как провести ретро для новичков, с...
сенькова   разное ретро для разных команд (как провести ретро для новичков, с...сенькова   разное ретро для разных команд (как провести ретро для новичков, с...
сенькова разное ретро для разных команд (как провести ретро для новичков, с...
 
мациевский путь самурая. уволить нельзя оставить
мациевский   путь самурая. уволить нельзя оставитьмациевский   путь самурая. уволить нельзя оставить
мациевский путь самурая. уволить нельзя оставить
 
лустин статические анализаторы систем 1с ad2015
лустин   статические анализаторы систем 1с ad2015лустин   статические анализаторы систем 1с ad2015
лустин статические анализаторы систем 1с ad2015
 
лосев контрольные карты шухарта в анализе деятельности Scrum команд
лосев   контрольные карты шухарта в анализе деятельности Scrum командлосев   контрольные карты шухарта в анализе деятельности Scrum команд
лосев контрольные карты шухарта в анализе деятельности Scrum команд
 
корецкий как мы улучшили экспертную оценку проектов
корецкий   как мы улучшили экспертную оценку проектовкорецкий   как мы улучшили экспертную оценку проектов
корецкий как мы улучшили экспертную оценку проектов
 
зиновьева повышение эффективности команды. ретроспектива как инструмент
зиновьева   повышение эффективности команды. ретроспектива как инструментзиновьева   повышение эффективности команды. ретроспектива как инструмент
зиновьева повышение эффективности команды. ретроспектива как инструмент
 
виноградова внедрение изменений без длинных документов, долгих согласований...
виноградова   внедрение изменений без длинных документов, долгих согласований...виноградова   внедрение изменений без длинных документов, долгих согласований...
виноградова внедрение изменений без длинных документов, долгих согласований...
 
верещак. построение культуры Dev ops. v0.5 copy
верещак. построение  культуры Dev ops. v0.5 copyверещак. построение  культуры Dev ops. v0.5 copy
верещак. построение культуры Dev ops. v0.5 copy
 
бородин об эмпирической разработке
бородин   об эмпирической разработкебородин   об эмпирической разработке
бородин об эмпирической разработке
 
богуславский Agile days непрерывное качество в непрерывной разработке
богуславский   Agile days непрерывное качество в непрерывной разработкебогуславский   Agile days непрерывное качество в непрерывной разработке
богуславский Agile days непрерывное качество в непрерывной разработке
 
атлыгина чеклисты для всех-всех-всех
атлыгина   чеклисты для всех-всех-всехатлыгина   чеклисты для всех-всех-всех
атлыгина чеклисты для всех-всех-всех
 

абилов а зачем нам функциональное программирование

  • 2.
  • 3.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13. A short poem by Afanasy Fet (1850) without a single verb
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19. let neighbours (x, y) = [ for i in x-1..x+1 do for j in y-1..y+1 do if not (i = x && j = y) then yield (i,j) ] let isAlive population cell = population |> List.exists ((=) cell) let aliveNeighbours population cell = neighbours cell |> List.filter (isAlive population)
  • 20. let survives population cell = aliveNeighbours population cell |> List.length |> fun x -> x >= 2 && x <= 3 let reproducible population cell = aliveNeighbours population cell |> List.length = 3
  • 21. let allDeadNeighbours population = population |> List.collect neighbours |> Set.ofList |> Set.toList |> List.filter (not << isAlive population) let nextGeneration population = List.append (population |> List.filter (survives population)) (allDeadNeighbours population |> List.filter (reproducible population)) Note use of colors: the only word in white is ”population". No variables!
  • 22.
  • 23. let isAlive population cell = population |> List.exists ((=) cell) let aliveNeighbours population cell = neighbours cell |> List.filter (isAlive population) let survives population cell = aliveNeighbours population cell |> List.length |> fun x -> x >= 2 && x <= 3 let reproducible population cell = aliveNeighbours population cell |> List.length = 3 let allDeadNeighbours population = population |> List.collect neighbours |> Set.ofList |> Set.toList |> List.filter (not << isAlive population) let nextGeneration population = List.append (population |> List.filter (survives population)) (allDeadNeighbours population |> List.filter (reproducible population))
  • 24. let neighbours (x, y) = [ for i in x-1..x+1 do for j in y-1..y+1 do if not (i = x && j = y) then yield (i,j) ] let neighbours (x, y, z) = [ for i in x-1..x+1 do for j in y-1..y+1 do for k in z-1..z+1 do if not (i = x && j = y && k = z) then yield (i,j,k) ]
  • 25. type Color = Red | Green | Blue | White | Gray | Black | Orange | Yellow | Brown let neighbours color = match color with | Red -> [Red; Orange; Brown] | Green -> [Green; Blue; Yellow] | Blue -> [Blue; Green] | White -> [White; Gray] | Black -> [Black; Gray] | Gray -> [Gray; Black; White] | Orange -> [Orange; Red; Yellow] | Yellow -> [Yellow; Orange; Green] | Brown -> [Brown; Red]
  • 26. let isAlive population cell = population |> List.exists ((=) cell) let aliveNeighbours population cell = neighbours cell |> List.filter (isAlive population) let survives population cell = aliveNeighbours population cell |> List.length |> fun x -> x >= 2 && x <= 3 let reproducible population cell = aliveNeighbours population cell |> List.length = 3 let allDeadNeighbours population = population |> List.collect neighbours |> Set.ofList |> Set.toList |> List.filter (not << isAlive population) let nextGeneration population = List.append (population |> List.filter (survives population)) (allDeadNeighbours population |> List.filter (reproducible population))
  • 27.
  • 28. // Sequential solution let nextGeneration population = List.append (population |> List.filter (survives population)) (allDeadNeighbours population |> List.filter (reproducible population)) // Parallel solution let nextGeneration population = seq { yield (population |> PList.filter (survives population)) yield (allDeadNeighbours population |> PList.filter (reproducible population)) } |> PSeq.toList
  • 29.
  • 30.
  • 32.
  • 33. type CardType = VISA | MasterCard | AmEx | Diners | Domestic type CardNumber = string type PaymentMethod = | Cash | Cheque of int | Card of CardType * CardNumber
  • 34. let calculateTips sum paymentMethod = match paymentMethod with | Cash -> sum * 0.05 | Cheque _ -> sum * 0.20 | Card (cardType, _) when cardType = Domestic -> sum * 0.10 | Card (_, _) -> sum * 0.15
  • 35. Term "Railway Oriented Programming" coined by ScottWlaschin
  • 37. Product |> placeInShoppingCart |> proceedToCheckout |> selectShipmentMethod |> selectPaymentMethod |> authorizePayment
  • 38. let ``Block should not change``() = let population = [(1,1); (1,2); (2,1); (2,2)] population |> nextGeneration |> should equal population
  • 40. let [<Given>] ``a customer buys a black jumper`` () = () let [<Given>] ``I have (.*) black jumpers left in stock`` (n : int) = stockItem <- { stockItem with Count = n } let [<When>] ``he returns the jumper for a refund`` () = stockItem <- { stockItem with Count = stockItem.Count + 1 } let [<Then>] ``I should have (.*) black jumpers in stock`` (n : int) = stockItem.Count |> should equal n