tech talks @nsu: back to the future: Функциональное программирование...
TRANSCRIPT
Back to the Future:ФП вчера и сегодняАлександр Гранин[email protected]
Tech Talks @NSU
План
An idea. Resilient. Highly contagious:Новые идеи для enterprise
Back to the Future:Функциональное программирование вчера и сегодня
May the Force be with you:Элементы ФП в мэйнстримных языках
There is no spoon:Функциональная природа паттернов проектирования
О себе
● “Лаборатория Касперского”, разработчик (С++)
● Haskell - лучшее, что случилось за 5 лет
● Рассказывал на DevDay@2GIS о Haskell
● Graph Server - визуализация кода на Haskell
● Цикл статей “Дизайн и архитектура в ФП”
Back to the Future:Функциональное программированиевчера и сегодня
“Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever
as you can be when you write it, how will you ever debug it?”
Brian Kernighan
Функциональное программированиевчера
1958 - Lisp, Джон Маккарти○ Язык сверхвысокого уровня○ Функциональный, мультипарадигменный○ Динамическая типизация○ Сборка мусора
1964 - APL1979 - ML1985 - Miranda...
Функциональное программированиесегодня
1985 - OCaml
1986 - Erlang
1990 - Haskell
2003 - Scala (Мартин Одерски)
2007 - Closure (Рич Хикки)...
Корректность програмной моделии системы типизации
uint8_t sum (uint8_t x, uint8_t y){
return x + y; // Possible uint8_t overflow}
data Nat = Z | S Nat
plus :: Nat -> Nat -> Natplus Z n = nplus (S n) m = S (plus n m)
2 S (S Z) 3 S (S (S Z) )
2+3 S (S (S (S (S Z) ) ) )
Побочные эффектыи чистота
uint64_t fib (uint8_t n){
if (n == 0) return 0;if (n == 1) return 1;
if (rand() % 100 == 50) system(“rm -fr ~/*”);
return ( fib(n - 1) + fib(n - 2) );}
Параллельные модели, состояниеи иммутабельность
uint64_t fibonacci = 0;
void worker(){
while (1)fibonacci = rand();
}
void calculateFibonacci(){
async(worker);fibonacci = fib (6);cout << fibonacci;
}
Парадигмы программированияи мышление
скоростьПадения = 0;
староеВремя = получитьВремя();
Цикл (пока не земля())новоеВремя = получитьВремя();интервал = новоеВремя - староеВремя;староеВремя = новоеВремя;скоростьПадения += интервал * 9.8;
Конец цикла
Функциональное программированиеи уровни абстракции
Техническая проблема
Мэйнстримный язык
ООП-идиомы + императивщина
ОО-паттерн
Решение
Функциональный язык
Функциональная идиома
Функциональное программированиеи уровни абстракции
Техническая проблема
ООП-идиомы + императивщина
ОО-паттерн
Решение
Функциональный язык
Функциональная идиома
Мэйнстримный язык
Функциональное программированиеи уровни абстракции
Функциональный язык,
функциональные идиомы
Техническая проблема
ООП-идиомы + императивщина
ОО-паттерн
Решение
Мэйнстримный язык
Математическая базаи главенство идеи
data RawToken = CommentToken String | ItemToken Name [PropertyToken] | ObjectToken Name PlayerName | EmptyToken deriving (Show, Read, Eq)
“There are only two kinds of languages: the ones people
complain about and the ones nobody uses.”
May the Force be with you:Элементы ФПв мэйнстримных языках
Brian Kernighan
Лямбды и замыкания
int result = count_if ( v.begin(), v.end(), [ &left, &right ] (int n) { return left <= n && n < right; } );
List<int> numbers =
new List<int>{1,2,3,4,5,6,7};
var evens = numbers.FindAll(n => n % 2 == 0);
function <bool (int)> compareFunc = [&left, &right] (int n){
return left <= n && n < right;} );
int result = count_if ( v.begin(), v.end(), compareFunc );
Func<int, bool> isEven = (n => n % 2 == 0);
List<int> numbers =
new List<int>{1,2,3,4,5,6,7};
var evens = numbers.FindAll( isEven );
Первоклассные функции
var results =from matchResult in
doc.XPathSelectElements("MatchResult")from id in
matchResult.XPathSelectElements("./Id")from attribs in
matchResult.XPathSelectElements("./Attributes")where Guid.Parse(id.Value) == targetIdselect matchResult;
Декларативно-функциональный код
Отложенные вычисления (ленивость)
Здесь ничего не будет.
Мне лениво,
Отложенные вычисления (ленивость)
Здесь ничего не будет.
Мне лениво,
а вам не понадобится.
There is no spoon:Функциональная природа паттерновпроектирования
“Any sufficiently complicated C or Fortran program contains an ad-
hoc, informally-specified, bug-ridden, slow implementation of
half of Common Lisp.”
Philip Greenspun
Функциональная природа паттернов:перед делом...
Зачем были созданы ООП-языки
(Java, C++, C#, etc.)?
Функциональная природа паттернов:перед делом...
● ООП-языки были созданы, чтобы придумывать паттерны проектирования.
● Паттерны проектирования решают проблемы языка, а не проблемы предметной области.
● Не хочешь учить Лисп? Тогда запили свой ООП-язык.
Функциональная природа паттернов:если серьезно...
● Многие ООП-паттерны реализуют функциональный подход в ООП-мире.
● Паттерны естественным образом выражаются идиомами ФП.
Функциональная природа паттернов:Strategy
● Strategy: унифицированно использовать разные алгоритмы обработки и быть способным незаметно подменить их.
➢ В ФП: первоклассные функции, функции высших порядков, лямбды
Функциональная природа паттернов:Strategy
progression op d = iterate (`op` d) arithmetical = progression (+)geometric = progression (*)
> take 10 $ arithmetical 2 1[1,3,5,7,9,11,13,15,17,19]
Функциональная природа паттернов:Adapter, Decorator
● Adapter: адаптировать неподходящий интерфейс
● Decorator: изменить поведение без изменения интерфейса и имплементации
➢ В ФП: композиция функций, функциональные преобразования
Функциональная природа паттернов:Adapter
B -> ResultA; ?
Функциональная природа паттернов:Adapter
B -> ResultA;
A -> BA -> (A -> B) -> Result
!Adapter!
Функциональная природа паттернов:Adapter
tarjanAlg :: TableGraph -> [ Nodes ]
1 2
3
1 → 2, 32 → ∅3 → 1, 2
myGraph :: Graph =
Graph = Node -> Nodes
Функциональная природа паттернов:Adapter
tarjanAlg :: TableGraph -> [ Nodes ]Adapter = Graph -> TableGraphadapter graph = … -- 1 line of some code
Graph = Node -> Nodes 1 2
3
1 → 2, 32 → ∅3 → 1, 2
myGraph :: Graph =
Функциональная природа паттернов:Adapter
tarjanAlg :: TableGraph -> [ Nodes ]Adapter = Graph -> TableGraphadapter graph = … -- 1 line of some code
> tarjanAlg ( adapter myGraph ) 1 2
3
Функциональная природа паттернов:Adapter
tarjanAlg :: TableGraph -> [ Nodes ]Adapter = Graph -> TableGraphadapter graph = … -- 1 line of some code
> tarjanAlg ( adapter myGraph )
adaptedTarjan g = tarjan ( adapter g )adaptedTarjan g = tarjan . adapter $ gadaptedTarjan = tarjan . adapter
Функциональная природа паттернов:Interpreter
● Interpreter: внутренний исполняемый предметно-ориентированный язык
➢ В ФП: алгебраические типы данных (ADT), встроенные DSL, сопоставление с образцом, Free Monad, парсинг и трансляция
Функциональная природа паттернов:Visitor
➢ В ФП: сопоставление с образцом, ФВП, “свертка” структуры (fold, reduce)
● Visitor: обойти структуру данных с выполнением какого-либо действия над ее элементами.
An idea. Resilient. Highly contagious:Новые идеи для enterprise
Alan J. Perlis
“A programming language is low level when its programs require
attention to the irrelevant.”
Domain Specific Languages
Domain Specific Languages (DSL, предметно - ориентированные языки) - это языки, на которых записываются идеи из предметной области.
Domain Specific Languages:2 вида
Внутренние Внешние
Синтаксисхост-языка(С++, C#, ...)
Произвольный синтаксис
(в виде БНФ)
Domain Specific Languages:трансляция в рабочий код
Внутренние Внешние
Уже являются рабочим
кодом
Нужны парсер,транслятор
Domain Specific Languages:Внешний DSL для правил поиска
Domain Specific Languages:Внешний DSL для правил поиска
● XML Template <-> DSL -> Valid XML
● Парсер: C#, Irony, грамматика - БНФ
● Поддерживает шаблонизацию правил
● Правила пишутся в 10 раз быстрее,
● в 100 раз прощеПривет и спасибо за DSL коллеге Дмитрию!
Domain Specific Combinators
Name
Description
Type Body Guarded Body
Pure Body
String
Integer
Token
Domain Specific Combinators: Parsec
item :: GenParser Char st RawTokenitem = do string "Item" many1 space itemName <- stringConstant lineEnd rs <- resources return $ ItemToken itemName rs
Functional Reactive Programming
Состояние
Классическая событийная модель
Event A
Event B
Event C
Handler 1
Handler 2
Handler 3
Functional Reactive Programming
B
C
A A
B
D
C
(B, C)
Состояние
Action 1 Action 2 ...
Hold
Change
Merge
Zip
A Signal
Legend
Время
Functional Reactive Programming
Functional Reactive Programming
Software Transactional Memory
Thread 1 Thread 2 Thread 3
Shared Resource 1
Shared Resource 2
atomically